regionModel.C 13 KB
Newer Older
1
2
3
4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
andy's avatar
andy committed
5
    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
6
7
8
9
10
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

andy's avatar
andy committed
11
12
13
14
    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
15
16
17
18
19
20
21

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
andy's avatar
andy committed
22
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
23
24
25
26
27
28

\*---------------------------------------------------------------------------*/

#include "regionModel.H"
#include "fvMesh.H"
#include "Time.H"
29
#include "mappedWallPolyPatch.H"
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "zeroGradientFvPatchFields.H"

// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

namespace Foam
{
namespace regionModels
{
    defineTypeNameAndDebug(regionModel, 0);
}
}

// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //

void Foam::regionModels::regionModel::constructMeshObjects()
{
    // construct region mesh
47
48
49
    if (!time_.foundObject<fvMesh>(regionName_))
    {
        regionMeshPtr_.reset
50
        (
51
            new fvMesh
52
            (
53
54
55
56
57
58
59
                IOobject
                (
                    regionName_,
                    time_.timeName(),
                    time_,
                    IOobject::MUST_READ
                )
60
            )
61
62
        );
    }
63
64
65
}


66
67
68
69
70
71
void Foam::regionModels::regionModel::constructMeshObjects
(
    const dictionary& dict
)
{
    // construct region mesh
72
73
74
    if (!time_.foundObject<fvMesh>(regionName_))
    {
        regionMeshPtr_.reset
75
        (
76
            new fvMesh
77
            (
78
79
80
81
82
83
84
                IOobject
                (
                    regionName_,
                    time_.timeName(),
                    time_,
                    IOobject::MUST_READ
                )
85
            )
86
87
        );
    }
88
89
90
}


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
void Foam::regionModels::regionModel::initialise()
{
    if (debug)
    {
        Pout<< "regionModel::initialise()" << endl;
    }

    label nBoundaryFaces = 0;
    DynamicList<label> primaryPatchIDs;
    DynamicList<label> intCoupledPatchIDs;
    const polyBoundaryMesh& rbm = regionMesh().boundaryMesh();

    forAll(rbm, patchI)
    {
        const polyPatch& regionPatch = rbm[patchI];
106
        if (isA<mappedWallPolyPatch>(regionPatch))
107
108
109
        {
            if (debug)
            {
110
                Pout<< "found " << mappedWallPolyPatch::typeName
111
112
113
114
115
116
117
                    <<  " " << regionPatch.name() << endl;
            }

            intCoupledPatchIDs.append(patchI);

            nBoundaryFaces += regionPatch.faceCells().size();

118
119
            const mappedPatchBase& mapPatch =
                refCast<const mappedPatchBase>(regionPatch);
120

121
122
            if
            (
sergio's avatar
sergio committed
123
124
125
126
                primaryMesh_.time().foundObject<polyMesh>
                (
                    mapPatch.sampleRegion()
                )
127
128
129
130
131
132
            )
            {

                const label primaryPatchI = mapPatch.samplePolyPatch().index();
                primaryPatchIDs.append(primaryPatchI);
            }
133
134
135
136
137
138
139
140
141
        }
    }

    primaryPatchIDs_.transfer(primaryPatchIDs);
    intCoupledPatchIDs_.transfer(intCoupledPatchIDs);

    if (nBoundaryFaces == 0)
    {
        WarningIn("regionModel::initialise()")
142
143
            << "Region model has no mapped boundary conditions - transfer "
            << "between regions will not be possible" << endl;
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
    }
}


// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //

bool Foam::regionModels::regionModel::read()
{
    if (regIOobject::read())
    {
        if (active_)
        {
            if (const dictionary* dictPtr = subDictPtr(modelName_ + "Coeffs"))
            {
                coeffs_ <<= *dictPtr;
            }

            infoOutput_.readIfPresent("infoOutput", *this);
        }

        return true;
    }
    else
    {
        return false;
    }
}


173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
bool Foam::regionModels::regionModel::read(const dictionary& dict)
{
    if (active_)
    {
        if (const dictionary* dictPtr = dict.subDictPtr(modelName_ + "Coeffs"))
        {
            coeffs_ <<= *dictPtr;
        }

        infoOutput_.readIfPresent("infoOutput", dict);

        return true;
    }
    else
    {
        return false;
    }
}


193
194
195
196
197
198
199
const Foam::AMIPatchToPatchInterpolation&
Foam::regionModels::regionModel::interRegionAMI
(
    const regionModel& nbrRegion,
    const label regionPatchI,
    const label nbrPatchI,
    const bool flip
200
) const
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
{
    label nbrRegionID = findIndex(interRegionAMINames_, nbrRegion.name());

    const fvMesh& nbrRegionMesh = nbrRegion.regionMesh();

    if (nbrRegionID != -1)
    {
        if (!interRegionAMI_[nbrRegionID].set(regionPatchI))
        {
            const polyPatch& p = regionMesh().boundaryMesh()[regionPatchI];
            const polyPatch& nbrP = nbrRegionMesh.boundaryMesh()[nbrPatchI];

            int oldTag = UPstream::msgType();
            UPstream::msgType() = oldTag + 1;

            interRegionAMI_[nbrRegionID].set
            (
                regionPatchI,
                new AMIPatchToPatchInterpolation
                (
                    p,
                    nbrP,
                    faceAreaIntersect::tmMesh,
andy's avatar
andy committed
224
                    AMIPatchToPatchInterpolation::imFaceAreaWeight,
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
                    flip
                )
            );

            UPstream::msgType() = oldTag;
        }

        return interRegionAMI_[nbrRegionID][regionPatchI];
    }
    else
    {
        label nbrRegionID = interRegionAMINames_.size();

        interRegionAMINames_.append(nbrRegion.name());

        const polyPatch& p = regionMesh().boundaryMesh()[regionPatchI];
        const polyPatch& nbrP = nbrRegionMesh.boundaryMesh()[nbrPatchI];

        label nPatch = regionMesh().boundaryMesh().size();


        interRegionAMI_.resize(nbrRegionID + 1);

        interRegionAMI_.set
        (
            nbrRegionID,
            new PtrList<AMIPatchToPatchInterpolation>(nPatch)
        );

        int oldTag = UPstream::msgType();
        UPstream::msgType() = oldTag + 1;

        interRegionAMI_[nbrRegionID].set
        (
            regionPatchI,
            new AMIPatchToPatchInterpolation
            (
                p,
                nbrP,
                faceAreaIntersect::tmMesh,
andy's avatar
andy committed
265
                AMIPatchToPatchInterpolation::imFaceAreaWeight,
266
267
268
269
270
271
272
273
274
275
276
                flip
            )
        );

        UPstream::msgType() = oldTag;

        return interRegionAMI_[nbrRegionID][regionPatchI];
    }
}


277
278
279
280
281
282
283
284
285
286
287
288
289
290
Foam::label Foam::regionModels::regionModel::nbrCoupledPatchID
(
    const regionModel& nbrRegion,
    const label regionPatchI
) const
{
    label nbrPatchI = -1;

    // region
    const fvMesh& nbrRegionMesh = nbrRegion.regionMesh();

    // boundary mesh
    const polyBoundaryMesh& nbrPbm = nbrRegionMesh.boundaryMesh();

291
292
293
294
295
    const polyBoundaryMesh& pbm = regionMesh().boundaryMesh();

    if (regionPatchI > pbm.size() - 1)
    {
        FatalErrorIn
296
        (
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
            "Foam::label Foam::regionModels::regionModel::nbrCoupledPatchID"
            "("
                "const regionModel&, "
                "const label"
            ") const"
        )
            << "region patch index out of bounds: "
            << "region patch index = " << regionPatchI
            << ", maximum index = " << pbm.size() - 1
            << abort(FatalError);
    }

    const polyPatch& pp = regionMesh().boundaryMesh()[regionPatchI];

    if (!isA<mappedPatchBase>(pp))
    {
        FatalErrorIn
        (
            "Foam::label Foam::regionModels::regionModel::nbrCoupledPatchID"
            "("
                "const regionModel&, "
                "const label"
            ") const"
        )
            << "Expected a " << mappedPatchBase::typeName
            << " patch, but found a " << pp.type() << abort(FatalError);
    }

    const mappedPatchBase& mpb = refCast<const mappedPatchBase>(pp);
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

    // sample patch name on the primary region
    const word& primaryPatchName = mpb.samplePatch();

    // find patch on nbr region that has the same sample patch name
    forAll(nbrRegion.intCoupledPatchIDs(), j)
    {
        const label nbrRegionPatchI = nbrRegion.intCoupledPatchIDs()[j];

        const mappedPatchBase& mpb =
            refCast<const mappedPatchBase>(nbrPbm[nbrRegionPatchI]);

        if (mpb.samplePatch() == primaryPatchName)
        {
            nbrPatchI = nbrRegionPatchI;
            break;
        }
    }

    if (nbrPatchI == -1)
    {
        const polyPatch& p = regionMesh().boundaryMesh()[regionPatchI];

        FatalErrorIn
        (
351
            "Foam::label Foam::regionModels::regionModel::nbrCoupledPatchID"
352
            "("
andy's avatar
andy committed
353
                "const regionModel&, "
354
355
356
357
358
359
360
361
362
363
364
365
                "const label"
            ") const"
        )
            << "Unable to find patch pair for local patch "
            << p.name() << " and region " << nbrRegion.name()
            << abort(FatalError);
    }

    return nbrPatchI;
}


366
367
// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

368
369
370
371
372
Foam::regionModels::regionModel::regionModel
(
    const fvMesh& mesh,
    const word& regionType
)
373
374
375
376
377
:
    IOdictionary
    (
        IOobject
        (
378
            regionType + "Properties",
379
            mesh.time().constant(),
380
            mesh.time(),
381
382
383
384
385
386
387
388
389
390
391
392
            IOobject::NO_READ,
            IOobject::NO_WRITE
        )
    ),
    primaryMesh_(mesh),
    time_(mesh.time()),
    active_(false),
    infoOutput_(false),
    modelName_("none"),
    regionMeshPtr_(NULL),
    coeffs_(dictionary::null),
    primaryPatchIDs_(),
393
    intCoupledPatchIDs_(),
andy's avatar
andy committed
394
    regionName_("none"),
395
396
397
    functions_(*this),
    interRegionAMINames_(),
    interRegionAMI_()
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
{}


Foam::regionModels::regionModel::regionModel
(
    const fvMesh& mesh,
    const word& regionType,
    const word& modelName,
    bool readFields
)
:
    IOdictionary
    (
        IOobject
        (
            regionType + "Properties",
            mesh.time().constant(),
415
            mesh.time(),
416
417
418
419
420
421
422
423
424
425
426
427
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    ),
    primaryMesh_(mesh),
    time_(mesh.time()),
    active_(lookup("active")),
    infoOutput_(true),
    modelName_(modelName),
    regionMeshPtr_(NULL),
    coeffs_(subOrEmptyDict(modelName + "Coeffs")),
    primaryPatchIDs_(),
428
    intCoupledPatchIDs_(),
andy's avatar
andy committed
429
430
    regionName_(lookup("regionName")),
    functions_(*this, subOrEmptyDict("functions"))
431
432
433
434
435
436
437
438
439
440
441
442
443
444
{
    if (active_)
    {
        constructMeshObjects();
        initialise();

        if (readFields)
        {
            read();
        }
    }
}


445
446
447
448
449
450
451
452
453
454
455
456
457
Foam::regionModels::regionModel::regionModel
(
    const fvMesh& mesh,
    const word& regionType,
    const word& modelName,
    const dictionary& dict,
    bool readFields
)
:
    IOdictionary
    (
        IOobject
        (
andy's avatar
andy committed
458
            regionType + "Properties",
459
            mesh.time().constant(),
460
            mesh.time(),
461
462
463
464
465
466
467
468
469
470
471
472
473
474
            IOobject::NO_READ,
            IOobject::NO_WRITE,
            true
        ),
        dict
    ),
    primaryMesh_(mesh),
    time_(mesh.time()),
    active_(dict.lookup("active")),
    infoOutput_(false),
    modelName_(modelName),
    regionMeshPtr_(NULL),
    coeffs_(dict.subOrEmptyDict(modelName + "Coeffs")),
    primaryPatchIDs_(),
475
    intCoupledPatchIDs_(),
andy's avatar
andy committed
476
477
    regionName_(dict.lookup("regionName")),
    functions_(*this, subOrEmptyDict("functions"))
478
479
480
481
482
483
484
485
486
487
488
489
490
491
{
    if (active_)
    {
        constructMeshObjects(dict);
        initialise();

        if (readFields)
        {
            read(dict);
        }
    }
}


492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //

Foam::regionModels::regionModel::~regionModel()
{}


// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //

void Foam::regionModels::regionModel::evolve()
{
    if (active_)
    {
        Info<< "\nEvolving " << modelName_ << " for region "
            << regionMesh().name() << endl;

507
        //read();
508
509
510
511
512

        preEvolveRegion();

        evolveRegion();

513
514
        postEvolveRegion();

515
516
517
518
519
520
521
522
523
524
525
        // Provide some feedback
        if (infoOutput_)
        {
            Info<< incrIndent;
            info();
            Info<< endl << decrIndent;
        }
    }
}


526
527
void Foam::regionModels::regionModel::preEvolveRegion()
{
andy's avatar
andy committed
528
    functions_.preEvolveRegion();
529
530
531
532
533
534
535
536
537
538
539
}


void Foam::regionModels::regionModel::evolveRegion()
{
    // do nothing
}


void Foam::regionModels::regionModel::postEvolveRegion()
{
andy's avatar
andy committed
540
    functions_.postEvolveRegion();
541
542
543
}


544
545
546
547
548
549
550
void Foam::regionModels::regionModel::info() const
{
    // do nothing
}


// ************************************************************************* //