/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
    \\  /    A nd           | Copyright (C) 2009-2010 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/>.

Application
    dsmcFields

Description
    Calculate intensive fields (U and T) from averaged extensive fields from a
    DSMC calculation.

Usage
    - dsmcFieldsCalc [OPTION]

    @param -noWrite \n
    Suppress output to files.

    @param -dictionary \<dictionary name\>\n
    Use specified dictionary.

    @param -noZero \n
    Ignore timestep 0.

    @param -constant \n
    Include the constant directory.

    @param -time \<time\>\n
    Apply only to specific time.

    @param -latestTime \n
    Only apply to latest time step.

    @param -case \<dir\> \n
    Specify the case directory

    @param -parallel \n
    Run the case in parallel

    @param -help \n
    Display short usage message

    @param -doc \n
    Display Doxygen documentation page

    @param -srcDoc \n
    Display source code

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

#include <postCalc/calc.H>
#include <finiteVolume/fvc.H>
#include <dsmc/dsmcCloud.H>
#include <utilityFunctionObjects/dsmcFields.H>
#include <OpenFOAM/IOobjectList.H>


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

namespace Foam
{
    template<class Type>
    bool addFieldsToList
    (
        const fvMesh& mesh,
        PtrList<GeometricField<Type, fvPatchField, volMesh> >& list,
        const wordList& fieldNames
    )
    {
        typedef GeometricField<Type, fvPatchField, volMesh> fieldType;

        label index = 0;
        forAll(fieldNames, i)
        {
            IOobject obj
            (
                fieldNames[i],
                mesh.time().timeName(),
                mesh,
                IOobject::MUST_READ
            );

            if (obj.headerOk() && obj.headerClassName() == fieldType::typeName)
            {
                list.set(index++, new fieldType(obj, mesh));
            }
            else
            {
                Info<< "Could not find " << fieldNames[i] << endl;

                return false;
            }
        }

        return true;
    }
}


void Foam::calc(const argList& args, const Time& runTime, const fvMesh& mesh)
{
    bool writeResults = !args.optionFound("noWrite");

    wordList extensiveVSFNames
    (
        IStringStream
        (
            "( \
                rhoNMean \
                rhoMMean \
                linearKEMean \
                internalEMean \
                iDofMean \
            )"
        )()
    );

    PtrList<volScalarField> extensiveVSFs(extensiveVSFNames.size());

    if
    (
        !addFieldsToList
        (
            mesh,
            extensiveVSFs,
            extensiveVSFNames
        )
    )
    {
        return;
    }

    wordList extensiveVVFNames
    (
        IStringStream
        (
            "( \
                momentumMean \
                fDMean \
            )"
        )()
    );

    PtrList<volVectorField> extensiveVVFs(extensiveVVFNames.size());

    if
    (
        !addFieldsToList
        (
            mesh,
            extensiveVVFs,
            extensiveVVFNames
        )
    )
    {
        return;
    }

    dsmcFields dF
    (
        "dsmcFieldsUtility",
        mesh,
        dictionary::null,
        false
    );

    if (writeResults)
    {
        dF.write();
    }
}

// ************************ vim: set sw=4 sts=4 et: ************************ //
