Forward compatibility: flex
[foam-extend-3.2.git] / src / dynamicMesh / dynamicTopoFvMesh / coupledMesh / coupledInfo.C
blob70b80a21a761e073c8aebc26165976ff407f28fa
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 "objectRegistry.H"
27 #include "foamTime.H"
28 #include "coupledInfo.H"
29 #include "emptyPolyPatch.H"
30 #include "processorPolyPatch.H"
31 #include "fixedValueFvPatchFields.H"
33 namespace Foam
36 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
38 // Construct given mesh, coupleMap and master / slave indices
39 template <class MeshType>
40 coupledInfo<MeshType>::coupledInfo
42     const MeshType& mesh,
43     const coupleMap& cMap,
44     const label mfzIndex,
45     const label sfzIndex
48     mesh_(mesh),
49     builtMaps_(false),
50     map_(cMap),
51     masterFaceZone_(mfzIndex),
52     slaveFaceZone_(sfzIndex)
56 // Construct from components
57 template <class MeshType>
58 coupledInfo<MeshType>::coupledInfo
60     const MeshType& mesh,
61     const bool isTwoDMesh,
62     const bool isLocal,
63     const bool isSend,
64     const label patchIndex,
65     const label mPatch,
66     const label sPatch,
67     const label mfzIndex,
68     const label sfzIndex
71     mesh_(mesh),
72     builtMaps_(false),
73     map_
74     (
75         IOobject
76         (
77             "coupleMap_"
78           + Foam::name(mPatch)
79           + "_To_"
80           + Foam::name(sPatch)
81           + word(isLocal ? "_Local" : "_Proc")
82           + word(isSend ? "_Send" : "_Recv"),
83             mesh.time().timeName(),
84             mesh,
85             IOobject::NO_READ,
86             IOobject::NO_WRITE,
87             true
88         ),
89         isTwoDMesh,
90         isLocal,
91         isSend,
92         patchIndex,
93         mPatch,
94         sPatch
95     ),
96     masterFaceZone_(mfzIndex),
97     slaveFaceZone_(sfzIndex)
101 //- Construct given addressing
102 template <class MeshType>
103 coupledInfo<MeshType>::subMeshMapper::subMeshMapper
105     const coupledInfo& cInfo,
106     const label patchI
109     sizeBeforeMapping_(cInfo.baseMesh().boundary()[patchI].size()),
110     directAddressing_
111     (
112         SubList<label>
113         (
114             cInfo.map().faceMap(),
115             cInfo.subMesh().boundary()[patchI].size(),
116             cInfo.subMesh().boundary()[patchI].patch().start()
117         )
118     )
120     // Offset indices
121     label pStart = cInfo.baseMesh().boundary()[patchI].patch().start();
123     forAll(directAddressing_, faceI)
124     {
125         directAddressing_[faceI] -= pStart;
126     }
130 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
132 // Return a const reference to the parent mesh
133 template <class MeshType>
134 const MeshType&
135 coupledInfo<MeshType>::baseMesh() const
137     return mesh_;
141 // Set a new subMesh
142 template <class MeshType>
143 void coupledInfo<MeshType>::setMesh
145     label index,
146     MeshType* mesh
149     subMesh_.set(mesh);
153 // Return a reference to the subMesh
154 template <class MeshType>
155 MeshType& coupledInfo<MeshType>::subMesh()
157     if (!subMesh_.valid())
158     {
159         FatalErrorIn("MeshType& coupledInfo::subMesh()")
160             << " Sub-mesh pointer has not been set."
161             << abort(FatalError);
162     }
164     return subMesh_();
168 // Return a const reference to the subMesh
169 template <class MeshType>
170 const MeshType& coupledInfo<MeshType>::subMesh() const
172     if (!subMesh_.valid())
173     {
174         FatalErrorIn("const MeshType& coupledInfo::subMesh() const")
175             << " Sub-mesh pointer has not been set."
176             << abort(FatalError);
177     }
179     return subMesh_();
183 // Return if maps have been built
184 template <class MeshType>
185 bool coupledInfo<MeshType>::builtMaps() const
187     return builtMaps_;
191 // Set internal state of maps as built
192 template <class MeshType>
193 void coupledInfo<MeshType>::setBuiltMaps()
195     builtMaps_ = true;
199 // Return a reference to the coupleMap
200 template <class MeshType>
201 coupleMap& coupledInfo<MeshType>::map()
203     return map_;
207 // Return a const reference to the coupleMap
208 template <class MeshType>
209 const coupleMap& coupledInfo<MeshType>::map() const
211     return map_;
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>
234 tmp<GeomField>
235 coupledInfo<MeshType>::subSetField
237     const GeomField& f,
238     const ZeroType& zeroValue,
239     const labelList& internalMapper
240 ) const
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)
261     {
262         if (patchI == (nPatches - 1))
263         {
264             // Artificially set last patch
265             patchFields.set
266             (
267                 patchI,
268                 PatchFieldType::New
269                 (
270                     emptyType,
271                     subMesh().boundary()[patchI],
272                     DimInternalField::null()
273                 )
274             );
275         }
276         else
277         {
278             patchFields.set
279             (
280                 patchI,
281                 PatchFieldType::New
282                 (
283                     PatchFieldType::calculatedType(),
284                     subMesh().boundary()[patchI],
285                     DimInternalField::null()
286                 )
287             );
288         }
289     }
291     // Create new field from pieces
292     tmp<GeomField> subFld
293     (
294         new GeomField
295         (
296             IOobject
297             (
298                 "subField_" + f.name(),
299                 subMesh().time().timeName(),
300                 subMesh(),
301                 IOobject::NO_READ,
302                 IOobject::NO_WRITE,
303                 false
304             ),
305             subMesh(),
306             f.dimensions(),
307             internalField,
308             patchFields
309         )
310     );
312     // Set correct references for patch internal fields,
313     // and map values from the supplied geometric field
314     GeomBdyFieldType& bf = subFld().boundaryField();
316     forAll(bf, patchI)
317     {
318         if (patchI == (nPatches - 1))
319         {
320             // Artificially set last patch
321             bf.set
322             (
323                 patchI,
324                 PatchFieldType::New
325                 (
326                     emptyType,
327                     subMesh().boundary()[patchI],
328                     subFld().dimensionedInternalField()
329                 )
330             );
331         }
332         else
333         if (isA<processorPolyPatch>(subMesh().boundary()[patchI].patch()))
334         {
335             bf.set
336             (
337                 patchI,
338                 PatchFieldType::New
339                 (
340                     processorType,
341                     subMesh().boundary()[patchI],
342                     subFld().dimensionedInternalField()
343                 )
344             );
346             // Avoid dealing with uninitialised values
347             // by artificially assigning to zero
348             bf[patchI] == zeroValue;
349         }
350         else
351         {
352             bf.set
353             (
354                 patchI,
355                 PatchFieldType::New
356                 (
357                     f.boundaryField()[patchI],
358                     subMesh().boundary()[patchI],
359                     subFld().dimensionedInternalField(),
360                     subMeshMapper(*this, patchI)
361                 )
362             );
363         }
364     }
366     return subFld;
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,
379     OSstream& strStream
380 ) const
382     strStream
383         << fieldType << token::NL
384         << token::BEGIN_BLOCK << token::NL;
386     forAll(fieldNames, i)
387     {
388         // Fetch object from registry
389         const objectRegistry& db = mesh_.thisDb();
391         const GeomField& fld = db.lookupObject<GeomField>(fieldNames[i]);
393         // Subset the field
394         tmp<GeomField> tsubFld = subSetField(fld, zeroValue, internalMapper);
396         // Send field subset through stream
397         strStream
398             << fieldNames[i]
399             << token::NL << token::BEGIN_BLOCK
400             << tsubFld
401             << token::NL << token::END_BLOCK
402             << token::NL;
403     }
405     strStream
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
419 ) const
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)
435     {
436         // Create and map the patch field values
437         label nPatches = subMesh().boundary().size();
439         // Create field parts
440         PtrList<PatchFieldType> patchFields(nPatches);
442         // Read dimensions
443         dimensionSet dimSet
444         (
445             fieldDicts.subDict(fieldNames[i]).lookup("dimensions")
446         );
448         // Read the internal field
449         InternalField internalField
450         (
451             "internalField",
452             fieldDicts.subDict(fieldNames[i]),
453             internalSize
454         );
456         // Create dummy types for initial field creation
457         forAll(patchFields, patchI)
458         {
459             if (patchI == (nPatches - 1))
460             {
461                 // Artificially set last patch
462                 patchFields.set
463                 (
464                     patchI,
465                     PatchFieldType::New
466                     (
467                         emptyType,
468                         subMesh().boundary()[patchI],
469                         DimInternalField::null()
470                     )
471                 );
472             }
473             else
474             {
475                 patchFields.set
476                 (
477                     patchI,
478                     PatchFieldType::New
479                     (
480                         PatchFieldType::calculatedType(),
481                         subMesh().boundary()[patchI],
482                         DimInternalField::null()
483                     )
484                 );
485             }
486         }
488         // Create field with dummy patches
489         fields.set
490         (
491             i,
492             new GeomField
493             (
494                 IOobject
495                 (
496                     fieldNames[i],
497                     subMesh().time().timeName(),
498                     subMesh(),
499                     IOobject::NO_READ,
500                     IOobject::NO_WRITE,
501                     false
502                 ),
503                 subMesh(),
504                 dimSet,
505                 internalField,
506                 patchFields
507             )
508         );
510         // Set correct references for patch internal fields,
511         // and fetch values from the supplied geometric field dictionaries
512         GeomBdyFieldType& bf = fields[i].boundaryField();
514         forAll(bf, patchI)
515         {
516             if (patchI == (nPatches - 1))
517             {
518                 // Artificially set last patch
519                 bf.set
520                 (
521                     patchI,
522                     PatchFieldType::New
523                     (
524                         emptyType,
525                         subMesh().boundary()[patchI],
526                         fields[i].dimensionedInternalField()
527                     )
528                 );
529             }
530             else
531             if (isA<processorPolyPatch>(subMesh().boundary()[patchI].patch()))
532             {
533                 bf.set
534                 (
535                     patchI,
536                     PatchFieldType::New
537                     (
538                         processorType,
539                         subMesh().boundary()[patchI],
540                         fields[i].dimensionedInternalField()
541                     )
542                 );
543             }
544             else
545             {
546                 bf.set
547                 (
548                     patchI,
549                     PatchFieldType::New
550                     (
551                         subMesh().boundary()[patchI],
552                         fields[i].dimensionedInternalField(),
553                         fieldDicts.subDict
554                         (
555                             fieldNames[i]
556                         ).subDict("boundaryField").subDict
557                         (
558                             subMesh().boundary()[patchI].name()
559                         )
560                     )
561                 );
562             }
563         }
564     }
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,
579     GeomField& field
582     // autoMap the internal field
583     field.internalField().autoMap(internalMapper);
585     // Reverse map for additional cells
586     forAll(srcFields, pI)
587     {
588         // Fetch field for this processor
589         const GeomField& srcField = srcFields[pI][srcIndex];
591         field.internalField().rmap
592         (
593             srcField.internalField(),
594             internalReverseMaps[pI]
595         );
596     }
598     // Map physical boundary-fields
599     forAll(boundaryMapper, patchI)
600     {
601         // autoMap the patchField
602         field.boundaryField()[patchI].autoMap(boundaryMapper[patchI]);
604         // Reverse map for additional patch faces
605         forAll(srcFields, pI)
606         {
607             // Fetch field for this processor
608             const GeomField& srcField = srcFields[pI][srcIndex];
610             field.boundaryField()[patchI].rmap
611             (
612                 srcField.boundaryField()[patchI],
613                 boundaryReverseMaps[pI][patchI]
614             );
615         }
616     }
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)
635     {
636         // Fetch field from registry
637         GeomField& field =
638         (
639             const_cast<GeomField&>
640             (
641                 mesh.lookupObject<GeomField>(names[indexI])
642             )
643         );
645         // Map the field
646         coupledInfo<MeshType>::resizeMap
647         (
648             indexI,
649             internalMapper,
650             internalReverseMaps,
651             boundaryMapper,
652             boundaryReverseMaps,
653             srcFields,
654             field
655         );
656     }
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)
675     {
676         // Fetch field from registry
677         GeomField& field = const_cast<GeomField&>(*fIter());
679         GeomBoundaryType& bf = field.boundaryField();
681         // Resize boundary
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++)
690         {
691             label oldPatchSize = bf[patchI].size();
693             newbf.set
694             (
695                 patchI,
696                 PatchFieldType::New
697                 (
698                     bf[patchI],
699                     boundary[patchI],
700                     field,
701                     subMeshMapper(oldPatchSize, identity(oldPatchSize))
702                 )
703             );
704         }
706         // Size up new patches
707         for (label patchI = nOldPatches; patchI < nPatches; patchI++)
708         {
709             newbf.set
710             (
711                 patchI,
712                 PatchFieldType::New
713                 (
714                     boundary[patchI].type(),
715                     boundary[patchI],
716                     field
717                 )
718             );
719         }
721         // Transfer contents with new patches
722         bf.transfer(newbf);
723     }
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
734     if (this == &rhs)
735     {
736         FatalErrorIn
737         (
738             "void coupledInfo::operator=(const Foam::coupledInfo&)"
739         )
740             << "Attempted assignment to self"
741             << abort(FatalError);
742     }
746 } // End namespace Foam
748 // ************************************************************************* //