BUGFIX: Illegal use of uninitialised value (backport)
[foam-extend-3.2.git] / src / dynamicMesh / dynamicFvMesh / dynamicTopoFvMesh / coupledInfo.C
blob82afb1396d6f02492684f732fee48285788a86eb
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright held by original author
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM 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 2 of the License, or (at your
14     option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "Time.H"
28 #include "coupledInfo.H"
29 #include "dynamicTopoFvMesh.H"
30 #include "emptyFvPatchFields.H"
31 #include "emptyFvsPatchFields.H"
32 #include "fixedValueFvPatchFields.H"
34 namespace Foam
37 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
39 // Constructor for coupledInfo
40 coupledInfo::coupledInfo
42     const dynamicTopoFvMesh& 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 coupledInfo::coupledInfo
58     const dynamicTopoFvMesh& mesh,
59     const bool isTwoDMesh,
60     const bool isLocal,
61     const bool isSend,
62     const label patchIndex,
63     const label mPatch,
64     const label sPatch,
65     const label mfzIndex,
66     const label sfzIndex
69     mesh_(mesh),
70     builtMaps_(false),
71     map_
72     (
73         IOobject
74         (
75             "coupleMap_"
76           + Foam::name(mPatch)
77           + "_To_"
78           + Foam::name(sPatch)
79           + word(isLocal ? "_Local" : "_Proc")
80           + word(isSend ? "_Send" : "_Recv"),
81             mesh.time().timeName(),
82             mesh,
83             IOobject::NO_READ,
84             IOobject::NO_WRITE,
85             true
86         ),
87         isTwoDMesh,
88         isLocal,
89         isSend,
90         patchIndex,
91         mPatch,
92         sPatch
93     ),
94     masterFaceZone_(mfzIndex),
95     slaveFaceZone_(sfzIndex)
99 //- Construct given addressing
100 coupledInfo::subMeshMapper::subMeshMapper
102     const coupledInfo& cInfo,
103     const label patchI
106     sizeBeforeMapping_(cInfo.baseMesh().boundary()[patchI].size()),
107     directAddressing_
108     (
109         SubList<label>
110         (
111             cInfo.map().faceMap(),
112             cInfo.subMesh().boundary()[patchI].size(),
113             cInfo.subMesh().boundary()[patchI].patch().start()
114         )
115     )
117     // Offset indices
118     label pStart = cInfo.baseMesh().boundary()[patchI].patch().start();
120     forAll(directAddressing_, faceI)
121     {
122         directAddressing_[faceI] -= pStart;
123     }
127 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
129 const dynamicTopoFvMesh& coupledInfo::baseMesh() const
131     return mesh_;
135 void coupledInfo::setMesh
137     label index,
138     dynamicTopoFvMesh* mesh
141     subMesh_.set(mesh);
145 dynamicTopoFvMesh& coupledInfo::subMesh()
147     if (!subMesh_.valid())
148     {
149         FatalErrorIn("dynamicTopoFvMesh& coupledInfo::subMesh()")
150             << " Sub-mesh pointer has not been set."
151             << abort(FatalError);
152     }
154     return subMesh_();
158 const dynamicTopoFvMesh& coupledInfo::subMesh() const
160     if (!subMesh_.valid())
161     {
162         FatalErrorIn("const dynamicTopoFvMesh& coupledInfo::subMesh() const")
163             << " Sub-mesh pointer has not been set."
164             << abort(FatalError);
165     }
167     return subMesh_();
171 bool coupledInfo::builtMaps() const
173     return builtMaps_;
177 void coupledInfo::setBuiltMaps()
179     builtMaps_ = true;
183 coupleMap& coupledInfo::map()
185     return map_;
189 const coupleMap& coupledInfo::map() const
191     return map_;
195 label coupledInfo::masterFaceZone() const
197     return masterFaceZone_;
201 label coupledInfo::slaveFaceZone() const
203     return slaveFaceZone_;
207 // Set subMesh centres
208 void coupledInfo::setCentres(PtrList<volVectorField>& centres) const
210     // Fetch reference to subMesh
211     const dynamicTopoFvMesh& mesh = subMesh();
213     // Set size
214     centres.setSize(1);
216     vectorField Cv(mesh.cellCentres());
217     vectorField Cf(mesh.faceCentres());
219     // Create and map the patch field values
220     label nPatches = mesh.boundary().size();
222     // Create field parts
223     PtrList<fvPatchField<vector> > volCentrePatches(nPatches);
225     // Over-ride and set all patches to fixedValue
226     for (label patchI = 0; patchI < nPatches; patchI++)
227     {
228         volCentrePatches.set
229         (
230             patchI,
231             new fixedValueFvPatchField<vector>
232             (
233                 mesh.boundary()[patchI],
234                 DimensionedField<vector, volMesh>::null()
235             )
236         );
238         // Slice field to patch (forced assignment)
239         volCentrePatches[patchI] ==
240         (
241             mesh.boundaryMesh()[patchI].patchSlice(Cf)
242         );
243     }
245     // Set the cell-centres pointer.
246     centres.set
247     (
248         0,
249         new volVectorField
250         (
251             IOobject
252             (
253                 "cellCentres",
254                 mesh.time().timeName(),
255                 mesh,
256                 IOobject::NO_READ,
257                 IOobject::NO_WRITE,
258                 false
259             ),
260             mesh,
261             dimLength,
262             SubField<vector>(Cv, mesh.nCells()),
263             volCentrePatches
264         )
265     );
269 // Subset volume field
270 template <class Type>
271 tmp<GeometricField<Type, fvPatchField, volMesh> >
272 coupledInfo::subSetVolField
274     const GeometricField<Type, fvPatchField, volMesh>& fld
275 ) const
277     // Create and map the internal-field values
278     Field<Type> internalField
279     (
280         fld.internalField(),
281         map().cellMap()
282     );
284     // Create and map the patch field values
285     label nPatches = subMesh().boundary().size();
286     PtrList<fvPatchField<Type> > patchFields(nPatches);
288     forAll(patchFields, patchI)
289     {
290         if (patchI == (nPatches - 1))
291         {
292             // Artificially set last patch
293             patchFields.set
294             (
295                 patchI,
296                 new emptyFvPatchField<Type>
297                 (
298                     subMesh().boundary()[patchI],
299                     DimensionedField<Type, volMesh>::null()
300                 )
301             );
302         }
303         else
304         {
305             patchFields.set
306             (
307                 patchI,
308                 fvPatchField<Type>::New
309                 (
310                     fld.boundaryField()[patchI],
311                     subMesh().boundary()[patchI],
312                     DimensionedField<Type, volMesh>::null(),
313                     subMeshMapper(*this, patchI)
314                 )
315             );
316         }
317     }
319     // Create new field from pieces
320     tmp<GeometricField<Type, fvPatchField, volMesh> > subFld
321     (
322         new GeometricField<Type, fvPatchField, volMesh>
323         (
324             IOobject
325             (
326                 "subField_" + fld.name(),
327                 subMesh().time().timeName(),
328                 subMesh(),
329                 IOobject::NO_READ,
330                 IOobject::NO_WRITE,
331                 false
332             ),
333             subMesh(),
334             fld.dimensions(),
335             internalField,
336             patchFields
337         )
338     );
340     return subFld;
344 // Subset surface field
345 template <class Type>
346 tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
347 coupledInfo::subSetSurfaceField
349     const GeometricField<Type, fvsPatchField, surfaceMesh>& fld
350 ) const
352     // Create and map the internal-field values
353     Field<Type> internalField
354     (
355         fld.internalField(),
356         SubList<label>
357         (
358             map().faceMap(),
359             subMesh().nInternalFaces()
360         )
361     );
363     // Create and map the patch field values
364     label nPatches = subMesh().boundary().size();
365     PtrList<fvsPatchField<Type> > patchFields(nPatches);
367     forAll(patchFields, patchI)
368     {
369         if (patchI == (nPatches - 1))
370         {
371             // Artificially set last patch
372             patchFields.set
373             (
374                 patchI,
375                 new emptyFvsPatchField<Type>
376                 (
377                     subMesh().boundary()[patchI],
378                     DimensionedField<Type, surfaceMesh>::null()
379                 )
380             );
381         }
382         else
383         {
384             patchFields.set
385             (
386                 patchI,
387                 fvsPatchField<Type>::New
388                 (
389                     fld.boundaryField()[patchI],
390                     subMesh().boundary()[patchI],
391                     DimensionedField<Type, surfaceMesh>::null(),
392                     subMeshMapper(*this, patchI)
393                 )
394             );
395         }
396     }
398     // Create new field from pieces
399     tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > subFld
400     (
401         new GeometricField<Type, fvsPatchField, surfaceMesh>
402         (
403             IOobject
404             (
405                 "subField_" + fld.name(),
406                 subMesh().time().timeName(),
407                 subMesh(),
408                 IOobject::NO_READ,
409                 IOobject::NO_WRITE,
410                 false
411             ),
412             subMesh(),
413             fld.dimensions(),
414             internalField,
415             patchFields
416         )
417     );
419     return subFld;
423 template <class Type>
424 void coupledInfo::mapVolField
426     const wordList& fieldNames,
427     const word& fieldType,
428     OSstream& strStream
429 ) const
431     strStream
432         << fieldType << token::NL
433         << token::BEGIN_BLOCK << token::NL;
435     forAll(fieldNames, i)
436     {
437         const GeometricField<Type, fvPatchField, volMesh>& fld =
438         (
439             mesh_.lookupObject
440             <
441                 GeometricField<Type, fvPatchField, volMesh>
442             >(fieldNames[i])
443         );
445         tmp<GeometricField<Type, fvPatchField, volMesh> > tsubFld =
446         (
447             subSetVolField(fld)
448         );
450         // Send field through stream
451         strStream
452             << fieldNames[i]
453             << token::NL << token::BEGIN_BLOCK
454             << tsubFld
455             << token::NL << token::END_BLOCK
456             << token::NL;
457     }
459     strStream
460         << token::END_BLOCK << token::NL;
464 template <class Type>
465 void coupledInfo::mapSurfaceField
467     const wordList& fieldNames,
468     const word& fieldType,
469     OSstream& strStream
470 ) const
472     strStream
473         << fieldType << token::NL
474         << token::BEGIN_BLOCK << token::NL;
476     forAll(fieldNames, i)
477     {
478         const GeometricField<Type, fvsPatchField, surfaceMesh>& fld =
479         (
480             mesh_.lookupObject
481             <
482                 GeometricField<Type, fvsPatchField, surfaceMesh>
483             >(fieldNames[i])
484         );
486         tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsubFld =
487         (
488             subSetSurfaceField(fld)
489         );
491         // Send field through stream
492         strStream
493             << fieldNames[i]
494             << token::NL << token::BEGIN_BLOCK
495             << tsubFld
496             << token::NL << token::END_BLOCK
497             << token::NL;
498     }
500     strStream
501         << token::END_BLOCK << token::NL;
505 // Set volume field pointer from input dictionary
506 template <class GeomField>
507 void coupledInfo::setField
509     const wordList& fieldNames,
510     const dictionary& fieldDicts,
511     PtrList<GeomField>& fields
512 ) const
514     // Size up the pointer list
515     fields.setSize(fieldNames.size());
517     forAll(fieldNames, i)
518     {
519         fields.set
520         (
521             i,
522             new GeomField
523             (
524                 IOobject
525                 (
526                     fieldNames[i],
527                     subMesh().time().timeName(),
528                     subMesh(),
529                     IOobject::NO_READ,
530                     IOobject::NO_WRITE,
531                     false
532                 ),
533                 subMesh(),
534                 fieldDicts.subDict(fieldNames[i])
535             )
536         );
537     }
541 template <class GeomField>
542 void coupledInfo::resizeMap
544     const label srcIndex,
545     const subMeshMapper& internalMapper,
546     const List<labelList>& internalReverseMaps,
547     const PtrList<subMeshMapper>& boundaryMapper,
548     const List<labelListList>& boundaryReverseMaps,
549     const List<PtrList<GeomField> >& srcFields,
550     GeomField& field
553     // autoMap the internal field
554     field.internalField().autoMap(internalMapper);
556     // Reverse map for additional cells
557     forAll(srcFields, pI)
558     {
559         // Fetch field for this processor
560         const GeomField& srcField = srcFields[pI][srcIndex];
562         field.internalField().rmap
563         (
564             srcField.internalField(),
565             internalReverseMaps[pI]
566         );
567     }
569     // Map physical boundary-fields
570     forAll(boundaryMapper, patchI)
571     {
572         // autoMap the patchField
573         field.boundaryField()[patchI].autoMap(boundaryMapper[patchI]);
575         // Reverse map for additional patch faces
576         forAll(srcFields, pI)
577         {
578             // Fetch field for this processor
579             const GeomField& srcField = srcFields[pI][srcIndex];
581             field.boundaryField()[patchI].rmap
582             (
583                 srcField.boundaryField()[patchI],
584                 boundaryReverseMaps[pI][patchI]
585             );
586         }
587     }
591 // Resize all fields in registry
592 template <class GeomField>
593 void coupledInfo::resizeMap
595     const wordList& names,
596     const objectRegistry& mesh,
597     const subMeshMapper& internalMapper,
598     const List<labelList>& internalReverseMaps,
599     const PtrList<subMeshMapper>& boundaryMapper,
600     const List<labelListList>& boundaryReverseMaps,
601     const List<PtrList<GeomField> >& srcFields
604     forAll(names, indexI)
605     {
606         // Fetch field from registry
607         GeomField& field =
608         (
609             const_cast<GeomField&>
610             (
611                 mesh.lookupObject<GeomField>(names[indexI])
612             )
613         );
615         // Map the field
616         coupledInfo::resizeMap
617         (
618             indexI,
619             internalMapper,
620             internalReverseMaps,
621             boundaryMapper,
622             boundaryReverseMaps,
623             srcFields,
624             field
625         );
626     }
630 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
632 void coupledInfo::operator=(const coupledInfo& rhs)
634     // Check for assignment to self
635     if (this == &rhs)
636     {
637         FatalErrorIn
638         (
639             "void coupledInfo::operator=(const Foam::coupledInfo&)"
640         )
641             << "Attempted assignment to self"
642             << abort(FatalError);
643     }
646 } // End namespace Foam
648 // ************************************************************************* //