catalystFaMesh.C 6.46 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    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.

    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
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.

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

#include "catalystFaMesh.H"
#include "addToRunTimeSelectionTable.H"
#include "faMesh.H"
Mark Olesen's avatar
Mark Olesen committed
29
#include "fvMesh.H"
30 31 32 33 34 35 36 37 38

#include <vtkCPDataDescription.h>
#include <vtkMultiBlockDataSet.h>
#include <vtkInformation.h>

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

namespace Foam
{
39
namespace catalyst
40
{
41 42 43 44 45 46 47 48
    defineTypeNameAndDebug(faMeshInput, 0);
    addNamedToRunTimeSelectionTable
    (
        catalystInput,
        faMeshInput,
        dictionary,
        area
    );
49 50 51 52 53 54
}
}


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

55
void Foam::catalyst::faMeshInput::update()
56
{
57 58 59 60 61
    // Backend requires a corresponding mesh
    backends_.filterKeys
    (
        [this](const word& k){ return meshes_.found(k); }
    );
62

63
    forAllConstIters(meshes_, iter)
64
    {
65
        if (!backends_.found(iter.key()))
66
        {
67
            backends_.set
68 69 70 71
            (
                iter.key(),
                new Foam::vtk::faMeshAdaptor(*(iter.object()))
            );
72 73 74 75 76 77 78
        }
    }
}


// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

79
Foam::catalyst::faMeshInput::faMeshInput
80 81 82 83 84 85
(
    const word& name,
    const Time& runTime,
    const dictionary& dict
)
:
86 87 88
    catalystInput(name),
    time_(runTime),
    regionName_(),
89 90 91
    selectAreas_(),
    selectFields_(),
    meshes_(),
92
    backends_()
93 94 95 96 97 98 99
{
    read(dict);
}


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

100
bool Foam::catalyst::faMeshInput::read(const dictionary& dict)
101
{
102
    catalystInput::read(dict);
103

104 105 106
    selectAreas_.clear();
    selectFields_.clear();
    backends_.clear();
107

108 109 110 111 112 113 114 115
    regionName_ =
        dict.lookupOrDefault<word>("region", polyMesh::defaultRegion);

    const objectRegistry& obr =
        time_.lookupObject<objectRegistry>(regionName_);

    // All possible meshes for the given region
    meshes_ = obr.lookupClass<faMesh>();
116 117 118 119 120 121 122 123

    dict.readIfPresent("areas", selectAreas_);

    if (selectAreas_.empty())
    {
        word areaName;
        if (!dict.readIfPresent("area", areaName))
        {
124
            wordList available = obr.sortedNames<faMesh>();
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

            if (available.size())
            {
                areaName = available.first();
            }
        }

        if (!areaName.empty())
        {
            selectAreas_.resize(1);
            selectAreas_.first() = areaName;
        }
    }

    // Restrict to specified meshes
140
    meshes_.filterKeys(selectAreas_);
141 142 143 144 145 146 147

    dict.lookup("fields") >> selectFields_;

    return true;
}


148
void Foam::catalyst::faMeshInput::update(polyMesh::readUpdateState state)
149
{
150
    // Trigger change of state
151

152 153 154 155 156
    const objectRegistry& obr =
        time_.lookupObject<objectRegistry>(regionName_);

    // Be really paranoid and verify if the mesh actually exists
    const wordList regionNames(backends_.toc());
157

158
    for (const word& regionName : regionNames)
159
    {
160
        if (meshes_.found(regionName) && obr.found(regionName))
161
        {
162
            backends_[regionName]->updateState(state);
163
        }
164
        else
165
        {
166 167
            backends_.erase(regionName);
            meshes_.erase(regionName);
168 169
        }
    }
170
}
171 172


173 174 175 176 177 178 179 180
Foam::label Foam::catalyst::faMeshInput::addChannels(dataQuery& dataq)
{
    update();   // Enforce sanity for backends and adaptor

    if (backends_.empty())
    {
        return 0;
    }
181

182
    // Gather all fields that we know how to convert
183 184 185 186 187 188 189
    wordHashSet allFields;
    forAllConstIters(backends_, iter)
    {
        allFields += iter.object()->knownFields(selectFields_);
    }


190
    dataq.set(name(), allFields);
191

192 193
    return 1;
}
194 195


196 197 198 199 200 201 202 203 204
bool Foam::catalyst::faMeshInput::convert
(
    dataQuery& dataq,
    outputChannels& outputs
)
{
    const wordList regionNames(backends_.sortedToc());

    if (regionNames.empty())
205
    {
206
        return false;  // skip - not available
207
    }
208

209 210 211 212 213 214 215 216 217 218
    // Single channel only

    label nChannels = 0;

    if (dataq.found(name()))
    {
        ++nChannels;
    }

    if (!nChannels)
219
    {
220
        return false;  // skip - not requested
221 222 223 224 225
    }


    // TODO: currently don't rely on the results from expecting much at all

226
    // Each region in a separate block
227
    unsigned int blockNo = 0;
228 229
    for (const word& regionName : regionNames)
    {
230 231
        auto dataset =
            backends_[regionName]->output(selectFields_);
232

233 234
        {
            const fileName channel = name();
235

236 237 238 239 240 241 242 243 244
            if (dataq.found(channel))
            {
                // Get existing or new
                vtkSmartPointer<vtkMultiBlockDataSet> block =
                    outputs.lookup
                    (
                        channel,
                        vtkSmartPointer<vtkMultiBlockDataSet>::New()
                    );
245

246
                block->SetBlock(blockNo, dataset);
247

248 249 250 251 252
                block->GetMetaData(blockNo)->Set
                (
                    vtkCompositeDataSet::NAME(),
                    regionName
                );
253

254 255 256
                outputs.set(channel, block);  // overwrites existing
            }
        }
257

258
        ++blockNo;
259 260 261 262 263 264
    }

    return true;
}


265
Foam::Ostream& Foam::catalyst::faMeshInput::print(Ostream& os) const
266
{
267 268 269 270
    os  << name() << nl
        <<"    areas   " << flatOutput(selectAreas_) << nl
        <<"    meshes  " << flatOutput(meshes_.sortedToc()) << nl
        <<"    fields  " << flatOutput(selectFields_) << nl;
271

272
    return os;
273 274 275 276
}


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