1 /*---------------------------------------------------------------------------*\
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 -------------------------------------------------------------------------------
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 "objectRegistry.H"
28 #include "coupledInfo.H"
29 #include "emptyPolyPatch.H"
30 #include "processorPolyPatch.H"
31 #include "fixedValueFvPatchFields.H"
36 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
38 // Construct given mesh, coupleMap and master / slave indices
39 template <class MeshType>
40 coupledInfo<MeshType>::coupledInfo
43 const coupleMap& cMap,
51 masterFaceZone_(mfzIndex),
52 slaveFaceZone_(sfzIndex)
56 // Construct from components
57 template <class MeshType>
58 coupledInfo<MeshType>::coupledInfo
61 const bool isTwoDMesh,
64 const label patchIndex,
81 + word(isLocal ? "_Local" : "_Proc")
82 + word(isSend ? "_Send" : "_Recv"),
83 mesh.time().timeName(),
96 masterFaceZone_(mfzIndex),
97 slaveFaceZone_(sfzIndex)
101 //- Construct given addressing
102 template <class MeshType>
103 coupledInfo<MeshType>::subMeshMapper::subMeshMapper
105 const coupledInfo& cInfo,
109 sizeBeforeMapping_(cInfo.baseMesh().boundary()[patchI].size()),
114 cInfo.map().faceMap(),
115 cInfo.subMesh().boundary()[patchI].size(),
116 cInfo.subMesh().boundary()[patchI].patch().start()
121 label pStart = cInfo.baseMesh().boundary()[patchI].patch().start();
123 forAll(directAddressing_, faceI)
125 directAddressing_[faceI] -= pStart;
130 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
132 // Return a const reference to the parent mesh
133 template <class MeshType>
135 coupledInfo<MeshType>::baseMesh() const
142 template <class MeshType>
143 void coupledInfo<MeshType>::setMesh
153 // Return a reference to the subMesh
154 template <class MeshType>
155 MeshType& coupledInfo<MeshType>::subMesh()
157 if (!subMesh_.valid())
159 FatalErrorIn("MeshType& coupledInfo::subMesh()")
160 << " Sub-mesh pointer has not been set."
161 << abort(FatalError);
168 // Return a const reference to the subMesh
169 template <class MeshType>
170 const MeshType& coupledInfo<MeshType>::subMesh() const
172 if (!subMesh_.valid())
174 FatalErrorIn("const MeshType& coupledInfo::subMesh() const")
175 << " Sub-mesh pointer has not been set."
176 << abort(FatalError);
183 // Return if maps have been built
184 template <class MeshType>
185 bool coupledInfo<MeshType>::builtMaps() const
191 // Set internal state of maps as built
192 template <class MeshType>
193 void coupledInfo<MeshType>::setBuiltMaps()
199 // Return a reference to the coupleMap
200 template <class MeshType>
201 coupleMap& coupledInfo<MeshType>::map()
207 // Return a const reference to the coupleMap
208 template <class MeshType>
209 const coupleMap& coupledInfo<MeshType>::map() const
215 // Return the master face zone ID
216 template <class MeshType>
217 label coupledInfo<MeshType>::masterFaceZone() const
219 return masterFaceZone_;
223 // Return the slave face zone ID
224 template <class MeshType>
225 label coupledInfo<MeshType>::slaveFaceZone() const
227 return slaveFaceZone_;
231 // Subset geometric field
232 template <class MeshType>
233 template <class GeomField, class ZeroType>
235 coupledInfo<MeshType>::subSetField
238 const ZeroType& zeroValue,
239 const labelList& internalMapper
242 typedef typename GeomField::InternalField InternalField;
243 typedef typename GeomField::PatchFieldType PatchFieldType;
244 typedef typename GeomField::GeometricBoundaryField GeomBdyFieldType;
245 typedef typename GeomField::DimensionedInternalField DimInternalField;
247 // Create and map the internal-field values
248 InternalField internalField(f.internalField(), internalMapper);
250 // Create and map the patch field values
251 label nPatches = subMesh().boundary().size();
252 PtrList<PatchFieldType> patchFields(nPatches);
254 // Define patch type names, assumed to be
255 // common for volume and surface fields
256 word emptyType(emptyPolyPatch::typeName);
257 word processorType(processorPolyPatch::typeName);
259 // Create dummy types for initial field creation
260 forAll(patchFields, patchI)
262 if (patchI == (nPatches - 1))
264 // Artificially set last patch
271 subMesh().boundary()[patchI],
272 DimInternalField::null()
283 PatchFieldType::calculatedType(),
284 subMesh().boundary()[patchI],
285 DimInternalField::null()
291 // Create new field from pieces
292 tmp<GeomField> subFld
298 "subField_" + f.name(),
299 subMesh().time().timeName(),
312 // Set correct references for patch internal fields,
313 // and map values from the supplied geometric field
314 GeomBdyFieldType& bf = subFld().boundaryField();
318 if (patchI == (nPatches - 1))
320 // Artificially set last patch
327 subMesh().boundary()[patchI],
328 subFld().dimensionedInternalField()
333 if (isA<processorPolyPatch>(subMesh().boundary()[patchI].patch()))
341 subMesh().boundary()[patchI],
342 subFld().dimensionedInternalField()
346 // Avoid dealing with uninitialised values
347 // by artificially assigning to zero
348 bf[patchI] == zeroValue;
357 f.boundaryField()[patchI],
358 subMesh().boundary()[patchI],
359 subFld().dimensionedInternalField(),
360 subMeshMapper(*this, patchI)
370 // Subset geometric fields from registry to output stream
371 template <class MeshType>
372 template <class GeomField, class ZeroType>
373 void coupledInfo<MeshType>::send
375 const wordList& fieldNames,
376 const word& fieldType,
377 const ZeroType& zeroValue,
378 const labelList& internalMapper,
383 << fieldType << token::NL
384 << token::BEGIN_BLOCK << token::NL;
386 forAll(fieldNames, i)
388 // Fetch object from registry
389 const objectRegistry& db = mesh_.thisDb();
391 const GeomField& fld = db.lookupObject<GeomField>(fieldNames[i]);
394 tmp<GeomField> tsubFld = subSetField(fld, zeroValue, internalMapper);
396 // Send field subset through stream
399 << token::NL << token::BEGIN_BLOCK
401 << token::NL << token::END_BLOCK
406 << token::END_BLOCK << token::NL;
410 // Set geometric field pointers from input dictionary
411 template <class MeshType>
412 template <class GeomField>
413 void coupledInfo<MeshType>::setField
415 const wordList& fieldNames,
416 const dictionary& fieldDicts,
417 const label internalSize,
418 PtrList<GeomField>& fields
421 typedef typename GeomField::InternalField InternalField;
422 typedef typename GeomField::PatchFieldType PatchFieldType;
423 typedef typename GeomField::GeometricBoundaryField GeomBdyFieldType;
424 typedef typename GeomField::DimensionedInternalField DimInternalField;
426 // Size up the pointer list
427 fields.setSize(fieldNames.size());
429 // Define patch type names, assumed to be
430 // common for volume and surface fields
431 word emptyType(emptyPolyPatch::typeName);
432 word processorType(processorPolyPatch::typeName);
434 forAll(fieldNames, i)
436 // Create and map the patch field values
437 label nPatches = subMesh().boundary().size();
439 // Create field parts
440 PtrList<PatchFieldType> patchFields(nPatches);
445 fieldDicts.subDict(fieldNames[i]).lookup("dimensions")
448 // Read the internal field
449 InternalField internalField
452 fieldDicts.subDict(fieldNames[i]),
456 // Create dummy types for initial field creation
457 forAll(patchFields, patchI)
459 if (patchI == (nPatches - 1))
461 // Artificially set last patch
468 subMesh().boundary()[patchI],
469 DimInternalField::null()
480 PatchFieldType::calculatedType(),
481 subMesh().boundary()[patchI],
482 DimInternalField::null()
488 // Create field with dummy patches
497 subMesh().time().timeName(),
510 // Set correct references for patch internal fields,
511 // and fetch values from the supplied geometric field dictionaries
512 GeomBdyFieldType& bf = fields[i].boundaryField();
516 if (patchI == (nPatches - 1))
518 // Artificially set last patch
525 subMesh().boundary()[patchI],
526 fields[i].dimensionedInternalField()
531 if (isA<processorPolyPatch>(subMesh().boundary()[patchI].patch()))
539 subMesh().boundary()[patchI],
540 fields[i].dimensionedInternalField()
551 subMesh().boundary()[patchI],
552 fields[i].dimensionedInternalField(),
556 ).subDict("boundaryField").subDict
558 subMesh().boundary()[patchI].name()
568 // Resize map for individual field
569 template <class MeshType>
570 template <class GeomField>
571 void coupledInfo<MeshType>::resizeMap
573 const label srcIndex,
574 const subMeshMapper& internalMapper,
575 const List<labelList>& internalReverseMaps,
576 const PtrList<subMeshMapper>& boundaryMapper,
577 const List<labelListList>& boundaryReverseMaps,
578 const List<PtrList<GeomField> >& srcFields,
582 // autoMap the internal field
583 field.internalField().autoMap(internalMapper);
585 // Reverse map for additional cells
586 forAll(srcFields, pI)
588 // Fetch field for this processor
589 const GeomField& srcField = srcFields[pI][srcIndex];
591 field.internalField().rmap
593 srcField.internalField(),
594 internalReverseMaps[pI]
598 // Map physical boundary-fields
599 forAll(boundaryMapper, patchI)
601 // autoMap the patchField
602 field.boundaryField()[patchI].autoMap(boundaryMapper[patchI]);
604 // Reverse map for additional patch faces
605 forAll(srcFields, pI)
607 // Fetch field for this processor
608 const GeomField& srcField = srcFields[pI][srcIndex];
610 field.boundaryField()[patchI].rmap
612 srcField.boundaryField()[patchI],
613 boundaryReverseMaps[pI][patchI]
620 // Resize all fields in registry
621 template <class MeshType>
622 template <class GeomField>
623 void coupledInfo<MeshType>::resizeMap
625 const wordList& names,
626 const objectRegistry& mesh,
627 const subMeshMapper& internalMapper,
628 const List<labelList>& internalReverseMaps,
629 const PtrList<subMeshMapper>& boundaryMapper,
630 const List<labelListList>& boundaryReverseMaps,
631 const List<PtrList<GeomField> >& srcFields
634 forAll(names, indexI)
636 // Fetch field from registry
639 const_cast<GeomField&>
641 mesh.lookupObject<GeomField>(names[indexI])
646 coupledInfo<MeshType>::resizeMap
660 // Resize boundaryFields for all fields in the registry
661 template <class MeshType>
662 template <class GeomField>
663 void coupledInfo<MeshType>::resizeBoundaries
665 const objectRegistry& mesh,
666 const fvBoundaryMesh& boundary
669 typedef typename GeomField::PatchFieldType PatchFieldType;
670 typedef typename GeomField::GeometricBoundaryField GeomBoundaryType;
672 HashTable<const GeomField*> fields(mesh.lookupClass<GeomField>());
674 forAllIter(typename HashTable<const GeomField*>, fields, fIter)
676 // Fetch field from registry
677 GeomField& field = const_cast<GeomField&>(*fIter());
679 GeomBoundaryType& bf = field.boundaryField();
682 label nPatches = boundary.size();
683 label nOldPatches = field.boundaryField().size();
685 // Create a new list of boundaries
686 PtrList<PatchFieldType> newbf(nPatches);
688 // Existing fields are mapped with new fvBoundaryMesh references
689 for (label patchI = 0; patchI < nOldPatches; patchI++)
691 label oldPatchSize = bf[patchI].size();
701 subMeshMapper(oldPatchSize, identity(oldPatchSize))
706 // Size up new patches
707 for (label patchI = nOldPatches; patchI < nPatches; patchI++)
714 boundary[patchI].type(),
721 // Transfer contents with new patches
727 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
729 // Disallow default bitwise assignment
730 template <class MeshType>
731 void coupledInfo<MeshType>::operator=(const coupledInfo& rhs)
733 // Check for assignment to self
738 "void coupledInfo::operator=(const Foam::coupledInfo&)"
740 << "Attempted assignment to self"
741 << abort(FatalError);
746 } // End namespace Foam
748 // ************************************************************************* //