catalystFvMesh.C 7.27 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 29 30 31 32 33 34 35 36
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
     \\/     M anipulation  | Copyright (C) 2018 CINECA
-------------------------------------------------------------------------------
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 "catalystFvMesh.H"
#include "addToRunTimeSelectionTable.H"

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

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

namespace Foam
{
37
namespace catalyst
38
{
39 40 41 42 43 44 45 46
    defineTypeNameAndDebug(fvMeshInput, 0);
    addNamedToRunTimeSelectionTable
    (
        catalystInput,
        fvMeshInput,
        dictionary,
        default
    );
47
}
48
} // End namespace Foam
49 50 51 52


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

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

61
    forAllConstIters(meshes_, iter)
62
    {
63 64 65
        const word& regionName = iter.key();

        if (!backends_.found(regionName))
66
        {
67 68 69 70 71 72 73 74 75 76 77 78
            auto backend =
                autoPtr<Foam::vtk::fvMeshAdaptor>::New
                (
                    *(iter.object()),
                    channelOpt_,
                    selectPatches_
                );

            // Special polyhedral treatment?
            backend->setDecompose(decomposeOpt_);

            backends_.set(regionName, backend);
79 80 81 82 83 84 85
        }
    }
}


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

86
Foam::catalyst::fvMeshInput::fvMeshInput
87 88 89 90 91 92
(
    const word& name,
    const Time& runTime,
    const dictionary& dict
)
:
93
    catalystInput(name),
94
    time_(runTime),
95 96
    channelOpt_(channelType::DEFAULT),
    decomposeOpt_(false),
97
    selectRegions_(),
98
    selectPatches_(),
99 100
    selectFields_(),
    meshes_(),
101
    backends_()
102 103 104 105 106 107 108
{
    read(dict);
}


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

109
bool Foam::catalyst::fvMeshInput::read(const dictionary& dict)
110
{
111 112
    catalystInput::read(dict);

113
    meshes_.clear();
114 115
    backends_.clear();
    selectRegions_.clear();
116 117
    selectPatches_.clear();
    selectFields_.clear();
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
    decomposeOpt_ = dict.lookupOrDefault("decompose", false);

    unsigned selected(channelType::NONE);

    if (dict.lookupOrDefault("internal", true))
    {
        selected |= channelType::INTERNAL;
    }
    if (dict.lookupOrDefault("boundary", true))
    {
        selected |= channelType::BOUNDARY;
    }

    channelOpt_ = channelType(selected);

    if (channelType::NONE == channelOpt_)
    {
        // Both are disabled - warn, and skip the rest of the input.
        WarningInFunction
            << name() << ":" << nl
            << "    both internal and boundary are disabled" << nl
            << "    check your input" << nl;
        return true;
    }
142

143 144 145
    // All possible meshes
    meshes_ = time_.lookupClass<fvMesh>();

146
    dict.readIfPresent("patches", selectPatches_);
147 148 149 150 151 152 153 154 155 156
    dict.readIfPresent("regions", selectRegions_);

    if (selectRegions_.empty())
    {
        selectRegions_.resize(1);
        selectRegions_.first() =
            dict.lookupOrDefault<word>("region", polyMesh::defaultRegion);
    }

    // Restrict to specified meshes
157
    meshes_.filterKeys(selectRegions_);
158

159
    dict.readEntry("fields", selectFields_);
160 161 162 163 164

    return true;
}


165
void Foam::catalyst::fvMeshInput::update(polyMesh::readUpdateState state)
166
{
167
    // Trigger change of state
168

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

172
    for (const word& regionName : regionNames)
173
    {
174
        if (meshes_.found(regionName) && time_.found(regionName))
175
        {
176
            backends_[regionName]->updateState(state);
177
        }
178
        else
179
        {
180 181
            backends_.erase(regionName);
            meshes_.erase(regionName);
182 183
        }
    }
184
}
185 186


187 188
Foam::label Foam::catalyst::fvMeshInput::addChannels(dataQuery& dataq)
{
189 190 191 192 193 194
    if (channelType::NONE == channelOpt_)
    {
        // Everything disabled - do nothing
        return 0;
    }

195 196 197 198 199 200
    update();   // Enforce sanity for backends and adaptor

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

202
    // Gather all fields that we know how to convert
203 204 205 206 207 208
    wordHashSet allFields;
    forAllConstIters(backends_, iter)
    {
        allFields += iter.object()->knownFields(selectFields_);
    }

209
    dataq.set(name(), allFields);
210

211
    return 1;
212
}
213

214 215 216 217 218 219 220

bool Foam::catalyst::fvMeshInput::convert
(
    dataQuery& dataq,
    outputChannels& outputs
)
{
221
    const word channelName(name());
222 223
    const wordList regionNames(backends_.sortedToc());

224
    if (regionNames.empty() || !dataq.found(channelName))
225
    {
226 227
        // Not available, or not requested
        return false;
228
    }
229
    if (channelType::NONE == channelOpt_)
230
    {
231 232
        // Safety: everything disabled (should have been caught before)
        return false;
233 234 235
    }


236 237
    // A separate block for each region
    unsigned int blockNo = 0;
238

239
    for (const word& regionName : regionNames)
240
    {
241
        auto dataset = backends_[regionName]->output(selectFields_);
242

243 244 245 246 247 248 249
        // Existing or new
        vtkSmartPointer<vtkMultiBlockDataSet> block =
            outputs.lookup
            (
                channelName,
                vtkSmartPointer<vtkMultiBlockDataSet>::New()
            );
250

251
        block->SetBlock(blockNo, dataset);
252

253 254 255 256 257
        block->GetMetaData(blockNo)->Set
        (
            vtkCompositeDataSet::NAME(),
            regionName                      // block name = region name
        );
258

259
        outputs.set(channelName, block);    // overwrites existing
260

261
        ++blockNo;
262 263 264 265 266 267
    }

    return true;
}


268
Foam::Ostream& Foam::catalyst::fvMeshInput::print(Ostream& os) const
269
{
270 271 272
    os  << name() << nl
        <<"    regions " << flatOutput(selectRegions_) << nl
        <<"    meshes  " << flatOutput(meshes_.sortedToc()) << nl
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
        <<"    fields  " << flatOutput(selectFields_) << nl
        <<"    output ";

    const unsigned selected(channelOpt_);

    if (!selected)
    {
        os << " none";
    }
    else
    {
        if (0 != (selected & (channelType::INTERNAL)))
        {
            os  <<" internal";
        }
        if (0 != (selected & (channelType::BOUNDARY)))
        {
            os  <<" boundary";
        }
    }
    os << nl;
294

295
    return os;
296 297 298 299
}


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