View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002499 | OpenFOAM | Bug | public | 2017-03-13 19:07 | 2017-03-16 12:00 |
Reporter | chrisk | Assigned To | henry | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Summary | 0002499: FunctionObject dsmcFields has no acess to Mean-Fields | ||||
Description | Hi, I am using dsmcFoam and I am averaging the fields with the option restartOnOutput set to on. When this option is set the order in which the functionObject are called is crucial. If the fields are first averaged like in the tutorial wedge15Ma5 and then the dsmcFields functionObject is called the calulation "fails" (the non-averaged fields are used), because of the option restartOnOutput the Mean-Fields are reseted/cleared in memory the moment before the calculation. Solution to that problem is change the order in which the functions are called in the controlDict, but doing this if I understand it right, the final timestep isn't used for the dsmcField-FunctionObject calculation, becauses it is not used in the averaging process, meaning the result is not what one would expect. Also there is that problem that when you try to calculate the dsmcField in postProcess, that the Mean-Fields are not loaded into the ObjectRegistry for the dsmcFoam solver. 1) So trying something like this: dsmcFoam -time 0.001 -postProcess 1) Results in: --> FOAM FATAL ERROR: request for volScalarField rhoNMean from objectRegistry region0 failed available objects of type volScalarField are 2) Trying: dsmcFoam -time 0.001 -postProcess -fields '(rhoNMean rhoMMean momentumMean linearKEMean internalEMean iDofMean fDMean)' 2) Results in the same error. 3) Trying: postProcess -fields '(rhoNMean rhoMMean momentumMean linearKEMean internalEMean iDofMean fDMean)' -time 0.001 -func dsmcFields 3) Results in: --> FOAM Warning : From function static bool Foam::functionObjectList::readFunctionObject(const Foam::string&, Foam::dictionary&, Foam::HashSet<>&, const Foam::word&) in file db/functionObjects/functionObjectList/functionObjectList.C at line 245 Cannot find functionObject file dsmcFields Time = 0.001 Reading fields: volScalarFields: iDofMean rhoMMean internalEMean rhoNMean linearKEMean volVectorFields: momentumMean fDMean So fields are loaded, but after that nothing happens. I hope my explenations are understandable and that it can be fixed. Chears, Christoph | ||||
Steps To Reproduce | -Use the wedge15Ma5 tutorial -Add the option restartOnOutput on; in the fieldAverage function -Set the nEquivalentParticles to 5e11 in constant/dsmcProperties (Or else dsmcField can not be calculated, because some rhoNMean values are 0; See /src/functionObjects/lagrangian/dsmcFields/dsmcFields.C Line 146) -Take a look in paraview and compare the UMean field, with one calculated in paraview (momentumMean/rhoMMean) -Change the order of the function calls in the controlDict and compare again | ||||
Tags | No tags attached. | ||||
|
Can you provide a patch to fix this problem? |
|
Not really. Only a very very bad workaround, that doesn't fix the problem with the crucial order of functions and memory clearing when restartOnOutput is set to on. With this "workaround" I am using the fieldAverage function during simulation and a motified dsmcField function (src/functionObjects/lagrangian/dsmcFields/dsmcFields.C), that loads the mean fields to the objectRegistry. Also this problem only exists, because with OF 4.x it's possible to calculate the dsmcFields during the simulation. In previous versions this was done after the simulation with the executable dsmcFieldsCalc. dsmcFields.C (11,382 bytes)
/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\/ 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 "dsmcFields.H" #include "volFields.H" #include "dictionary.H" #include "dsmcCloud.H" #include "constants.H" #include "addToRunTimeSelectionTable.H" using namespace Foam::constant; // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { namespace functionObjects { defineTypeNameAndDebug(dsmcFields, 0); addToRunTimeSelectionTable ( functionObject, dsmcFields, dictionary ); } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::functionObjects::dsmcFields::dsmcFields ( const word& name, const Time& runTime, const dictionary& dict ) : functionObject(name), obr_ ( runTime.lookupObject<objectRegistry> ( dict.lookupOrDefault("region", polyMesh::defaultRegion) ) ) { if (!isA<fvMesh>(obr_)) { FatalErrorInFunction << "objectRegistry is not an fvMesh" << exit(FatalError); } read(dict); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::functionObjects::dsmcFields::~dsmcFields() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // bool Foam::functionObjects::dsmcFields::read(const dictionary& dict) { return true; } bool Foam::functionObjects::dsmcFields::execute() { return true; } bool Foam::functionObjects::dsmcFields::write() { word rhoNName = "rhoN"; word rhoMName = "rhoM"; word momentumName = "momentum"; word linearKEName = "linearKE"; word internalEName = "internalE"; word iDofName = "iDof"; word fDName = "fD"; //obr_.lookupObject<volScalarField>() /*volScalarField rhoNMean ( IOobject ( rhoNMeanName, obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1 );*/ const volScalarField& baseField1 = obr_.lookupObject<volScalarField>(rhoNName); obr_.store ( new volScalarField ( IOobject ( rhoNName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField1 ) ); const volScalarField& baseField2 = obr_.lookupObject<volScalarField>(rhoMName); obr_.store ( new volScalarField ( IOobject ( rhoMName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField2 ) ); const volVectorField& baseField3 = obr_.lookupObject<volVectorField>(momentumName); obr_.store ( new volVectorField ( IOobject ( momentumName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField3 ) ); const volScalarField& baseField4 = obr_.lookupObject<volScalarField>(linearKEName); obr_.store ( new volScalarField ( IOobject ( linearKEName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField4 ) ); const volScalarField& baseField5 = obr_.lookupObject<volScalarField>(internalEName); obr_.store ( new volScalarField ( IOobject ( internalEName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField5 ) ); const volScalarField& baseField6 = obr_.lookupObject<volScalarField>(iDofName); obr_.store ( new volScalarField ( IOobject ( iDofName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField6 ) ); const volVectorField& baseField7 = obr_.lookupObject<volVectorField>(fDName); obr_.store ( new volVectorField ( IOobject ( fDName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField7 ) ); const volScalarField& rhoNMean = obr_.lookupObject<volScalarField> ( rhoNName + "Mean" ); const volScalarField& rhoMMean = obr_.lookupObject<volScalarField> ( rhoMName + "Mean" ); const volVectorField& momentumMean = obr_.lookupObject<volVectorField> ( momentumName + "Mean" ); const volScalarField& linearKEMean = obr_.lookupObject<volScalarField> ( linearKEName + "Mean" ); const volScalarField& internalEMean = obr_.lookupObject<volScalarField> ( internalEName + "Mean" ); const volScalarField& iDofMean = obr_.lookupObject<volScalarField> ( iDofName + "Mean" ); const volVectorField& fDMean = obr_.lookupObject<volVectorField> ( fDName + "Mean" ); if (min(mag(rhoNMean)).value() > VSMALL) { Info<< "Calculating dsmcFields." << endl; Info<< " Calculating UMean field." << endl; volVectorField UMean ( IOobject ( "UMean", obr_.time().timeName(), obr_, IOobject::NO_READ ), momentumMean/rhoMMean ); Info<< " Calculating translationalT field." << endl; volScalarField translationalT ( IOobject ( "translationalT", obr_.time().timeName(), obr_, IOobject::NO_READ ), 2.0/(3.0*physicoChemical::k.value()*rhoNMean) *(linearKEMean - 0.5*rhoMMean*(UMean & UMean)) ); Info<< " Calculating internalT field." << endl; volScalarField internalT ( IOobject ( "internalT", obr_.time().timeName(), obr_, IOobject::NO_READ ), (2.0/physicoChemical::k.value())*(internalEMean/iDofMean) ); Info<< " Calculating overallT field." << endl; volScalarField overallT ( IOobject ( "overallT", obr_.time().timeName(), obr_, IOobject::NO_READ ), 2.0/(physicoChemical::k.value()*(3.0*rhoNMean + iDofMean)) *(linearKEMean - 0.5*rhoMMean*(UMean & UMean) + internalEMean) ); Info<< " Calculating pressure field." << endl; volScalarField p ( IOobject ( "p", obr_.time().timeName(), obr_, IOobject::NO_READ ), physicoChemical::k.value()*rhoNMean*translationalT ); const fvMesh& mesh = fDMean.mesh(); volScalarField::Boundary& pBf = p.boundaryFieldRef(); forAll(mesh.boundaryMesh(), i) { const polyPatch& patch = mesh.boundaryMesh()[i]; if (isA<wallPolyPatch>(patch)) { pBf[i] = fDMean.boundaryField()[i] & (patch.faceAreas()/mag(patch.faceAreas())); } } Info<< " mag(UMean) max/min : " << max(mag(UMean)).value() << " " << min(mag(UMean)).value() << endl; Info<< " translationalT max/min : " << max(translationalT).value() << " " << min(translationalT).value() << endl; Info<< " internalT max/min : " << max(internalT).value() << " " << min(internalT).value() << endl; Info<< " overallT max/min : " << max(overallT).value() << " " << min(overallT).value() << endl; Info<< " p max/min : " << max(p).value() << " " << min(p).value() << endl; UMean.write(); translationalT.write(); internalT.write(); overallT.write(); p.write(); Info<< "dsmcFields written." << nl << endl; return true; } else { Info<< "Small value (" << min(mag(rhoNMean)) << ") found in rhoNMean field. " << "Not calculating dsmcFields to avoid division by zero." << endl; return false; } } // ************************************************************************* // |
|
dsmcFields-2.C (11,382 bytes)
/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\/ 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 "dsmcFields.H" #include "volFields.H" #include "dictionary.H" #include "dsmcCloud.H" #include "constants.H" #include "addToRunTimeSelectionTable.H" using namespace Foam::constant; // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { namespace functionObjects { defineTypeNameAndDebug(dsmcFields, 0); addToRunTimeSelectionTable ( functionObject, dsmcFields, dictionary ); } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::functionObjects::dsmcFields::dsmcFields ( const word& name, const Time& runTime, const dictionary& dict ) : functionObject(name), obr_ ( runTime.lookupObject<objectRegistry> ( dict.lookupOrDefault("region", polyMesh::defaultRegion) ) ) { if (!isA<fvMesh>(obr_)) { FatalErrorInFunction << "objectRegistry is not an fvMesh" << exit(FatalError); } read(dict); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::functionObjects::dsmcFields::~dsmcFields() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // bool Foam::functionObjects::dsmcFields::read(const dictionary& dict) { return true; } bool Foam::functionObjects::dsmcFields::execute() { return true; } bool Foam::functionObjects::dsmcFields::write() { word rhoNName = "rhoN"; word rhoMName = "rhoM"; word momentumName = "momentum"; word linearKEName = "linearKE"; word internalEName = "internalE"; word iDofName = "iDof"; word fDName = "fD"; //obr_.lookupObject<volScalarField>() /*volScalarField rhoNMean ( IOobject ( rhoNMeanName, obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1 );*/ const volScalarField& baseField1 = obr_.lookupObject<volScalarField>(rhoNName); obr_.store ( new volScalarField ( IOobject ( rhoNName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField1 ) ); const volScalarField& baseField2 = obr_.lookupObject<volScalarField>(rhoMName); obr_.store ( new volScalarField ( IOobject ( rhoMName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField2 ) ); const volVectorField& baseField3 = obr_.lookupObject<volVectorField>(momentumName); obr_.store ( new volVectorField ( IOobject ( momentumName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField3 ) ); const volScalarField& baseField4 = obr_.lookupObject<volScalarField>(linearKEName); obr_.store ( new volScalarField ( IOobject ( linearKEName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField4 ) ); const volScalarField& baseField5 = obr_.lookupObject<volScalarField>(internalEName); obr_.store ( new volScalarField ( IOobject ( internalEName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField5 ) ); const volScalarField& baseField6 = obr_.lookupObject<volScalarField>(iDofName); obr_.store ( new volScalarField ( IOobject ( iDofName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField6 ) ); const volVectorField& baseField7 = obr_.lookupObject<volVectorField>(fDName); obr_.store ( new volVectorField ( IOobject ( fDName + "Mean", obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1*baseField7 ) ); const volScalarField& rhoNMean = obr_.lookupObject<volScalarField> ( rhoNName + "Mean" ); const volScalarField& rhoMMean = obr_.lookupObject<volScalarField> ( rhoMName + "Mean" ); const volVectorField& momentumMean = obr_.lookupObject<volVectorField> ( momentumName + "Mean" ); const volScalarField& linearKEMean = obr_.lookupObject<volScalarField> ( linearKEName + "Mean" ); const volScalarField& internalEMean = obr_.lookupObject<volScalarField> ( internalEName + "Mean" ); const volScalarField& iDofMean = obr_.lookupObject<volScalarField> ( iDofName + "Mean" ); const volVectorField& fDMean = obr_.lookupObject<volVectorField> ( fDName + "Mean" ); if (min(mag(rhoNMean)).value() > VSMALL) { Info<< "Calculating dsmcFields." << endl; Info<< " Calculating UMean field." << endl; volVectorField UMean ( IOobject ( "UMean", obr_.time().timeName(), obr_, IOobject::NO_READ ), momentumMean/rhoMMean ); Info<< " Calculating translationalT field." << endl; volScalarField translationalT ( IOobject ( "translationalT", obr_.time().timeName(), obr_, IOobject::NO_READ ), 2.0/(3.0*physicoChemical::k.value()*rhoNMean) *(linearKEMean - 0.5*rhoMMean*(UMean & UMean)) ); Info<< " Calculating internalT field." << endl; volScalarField internalT ( IOobject ( "internalT", obr_.time().timeName(), obr_, IOobject::NO_READ ), (2.0/physicoChemical::k.value())*(internalEMean/iDofMean) ); Info<< " Calculating overallT field." << endl; volScalarField overallT ( IOobject ( "overallT", obr_.time().timeName(), obr_, IOobject::NO_READ ), 2.0/(physicoChemical::k.value()*(3.0*rhoNMean + iDofMean)) *(linearKEMean - 0.5*rhoMMean*(UMean & UMean) + internalEMean) ); Info<< " Calculating pressure field." << endl; volScalarField p ( IOobject ( "p", obr_.time().timeName(), obr_, IOobject::NO_READ ), physicoChemical::k.value()*rhoNMean*translationalT ); const fvMesh& mesh = fDMean.mesh(); volScalarField::Boundary& pBf = p.boundaryFieldRef(); forAll(mesh.boundaryMesh(), i) { const polyPatch& patch = mesh.boundaryMesh()[i]; if (isA<wallPolyPatch>(patch)) { pBf[i] = fDMean.boundaryField()[i] & (patch.faceAreas()/mag(patch.faceAreas())); } } Info<< " mag(UMean) max/min : " << max(mag(UMean)).value() << " " << min(mag(UMean)).value() << endl; Info<< " translationalT max/min : " << max(translationalT).value() << " " << min(translationalT).value() << endl; Info<< " internalT max/min : " << max(internalT).value() << " " << min(internalT).value() << endl; Info<< " overallT max/min : " << max(overallT).value() << " " << min(overallT).value() << endl; Info<< " p max/min : " << max(p).value() << " " << min(p).value() << endl; UMean.write(); translationalT.write(); internalT.write(); overallT.write(); p.write(); Info<< "dsmcFields written." << nl << endl; return true; } else { Info<< "Small value (" << min(mag(rhoNMean)) << ") found in rhoNMean field. " << "Not calculating dsmcFields to avoid division by zero." << endl; return false; } } // ************************************************************************* // |
|
* I use the motified dsmcField function after the simulation with: dsmcFoam -postProcess |
|
When you have had time to complete a more consistent fix for the problem please submit it for inclusion on OpenFOAM. |
|
Small fix to the workarond, MUST_READ prints a lot of warnings. I can look into it more when I finish my master thesis, but for now I don't have much time on my hand. dsmcFields-WorkAround.C (11,626 bytes)
/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\/ 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 "dsmcFields.H" #include "volFields.H" #include "dictionary.H" #include "dsmcCloud.H" #include "constants.H" #include "addToRunTimeSelectionTable.H" using namespace Foam::constant; // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { namespace functionObjects { defineTypeNameAndDebug(dsmcFields, 0); addToRunTimeSelectionTable ( functionObject, dsmcFields, dictionary ); } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::functionObjects::dsmcFields::dsmcFields ( const word& name, const Time& runTime, const dictionary& dict ) : functionObject(name), obr_ ( runTime.lookupObject<objectRegistry> ( dict.lookupOrDefault("region", polyMesh::defaultRegion) ) ) { if (!isA<fvMesh>(obr_)) { FatalErrorInFunction << "objectRegistry is not an fvMesh" << exit(FatalError); } read(dict); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::functionObjects::dsmcFields::~dsmcFields() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // bool Foam::functionObjects::dsmcFields::read(const dictionary& dict) { return true; } bool Foam::functionObjects::dsmcFields::execute() { return true; } bool Foam::functionObjects::dsmcFields::write() { word rhoNName = "rhoN"; word rhoNMeanName = "rhoNMean"; word rhoMName = "rhoM"; word rhoMMeanName = "rhoMMean"; word momentumName = "momentum"; word momentumMeanName = "momentumMean"; word linearKEName = "linearKE"; word linearKEMeanName = "linearKEMean"; word internalEName = "internalE"; word internalEMeanName = "internalEMean"; word iDofName = "iDof"; word iDofMeanName = "iDofMean"; word fDName = "fD"; word fDMeanName = "fDMean"; //obr_.lookupObject<volScalarField>() /*volScalarField rhoNMean ( IOobject ( rhoNMeanName, obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::MUST_READ, IOobject::NO_WRITE ), 1 );*/ const volScalarField& baseField1 = obr_.lookupObject<volScalarField>(rhoNName); obr_.store ( new volScalarField ( IOobject ( rhoNMeanName, obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), 1*baseField1 ) ); const volScalarField& baseField2 = obr_.lookupObject<volScalarField>(rhoMName); obr_.store ( new volScalarField ( IOobject ( rhoMMeanName, obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), 1*baseField2 ) ); const volVectorField& baseField3 = obr_.lookupObject<volVectorField>(momentumName); obr_.store ( new volVectorField ( IOobject ( momentumMeanName, obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), 1*baseField3 ) ); const volScalarField& baseField4 = obr_.lookupObject<volScalarField>(linearKEName); obr_.store ( new volScalarField ( IOobject ( linearKEMeanName, obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), 1*baseField4 ) ); const volScalarField& baseField5 = obr_.lookupObject<volScalarField>(internalEName); obr_.store ( new volScalarField ( IOobject ( internalEMeanName, obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), 1*baseField5 ) ); const volScalarField& baseField6 = obr_.lookupObject<volScalarField>(iDofName); obr_.store ( new volScalarField ( IOobject ( iDofMeanName, obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), 1*baseField6 ) ); const volVectorField& baseField7 = obr_.lookupObject<volVectorField>(fDName); obr_.store ( new volVectorField ( IOobject ( fDMeanName, obr_.time().timeName(obr_.time().startTime().value()), obr_, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), 1*baseField7 ) ); const volScalarField& rhoNMean = obr_.lookupObject<volScalarField> ( rhoNMeanName ); const volScalarField& rhoMMean = obr_.lookupObject<volScalarField> ( rhoMMeanName ); const volVectorField& momentumMean = obr_.lookupObject<volVectorField> ( momentumMeanName ); const volScalarField& linearKEMean = obr_.lookupObject<volScalarField> ( linearKEMeanName ); const volScalarField& internalEMean = obr_.lookupObject<volScalarField> ( internalEMeanName ); const volScalarField& iDofMean = obr_.lookupObject<volScalarField> ( iDofMeanName ); const volVectorField& fDMean = obr_.lookupObject<volVectorField> ( fDMeanName ); if (min(mag(rhoNMean)).value() > VSMALL) { Info<< "Calculating dsmcFields." << endl; Info<< " Calculating UMean field." << endl; volVectorField UMean ( IOobject ( "UMean", obr_.time().timeName(), obr_, IOobject::NO_READ ), momentumMean/rhoMMean ); Info<< " Calculating translationalT field." << endl; volScalarField translationalT ( IOobject ( "translationalT", obr_.time().timeName(), obr_, IOobject::NO_READ ), 2.0/(3.0*physicoChemical::k.value()*rhoNMean) *(linearKEMean - 0.5*rhoMMean*(UMean & UMean)) ); Info<< " Calculating internalT field." << endl; volScalarField internalT ( IOobject ( "internalT", obr_.time().timeName(), obr_, IOobject::NO_READ ), (2.0/physicoChemical::k.value())*(internalEMean/iDofMean) ); Info<< " Calculating overallT field." << endl; volScalarField overallT ( IOobject ( "overallT", obr_.time().timeName(), obr_, IOobject::NO_READ ), 2.0/(physicoChemical::k.value()*(3.0*rhoNMean + iDofMean)) *(linearKEMean - 0.5*rhoMMean*(UMean & UMean) + internalEMean) ); Info<< " Calculating pressure field." << endl; volScalarField p ( IOobject ( "p", obr_.time().timeName(), obr_, IOobject::NO_READ ), physicoChemical::k.value()*rhoNMean*translationalT ); const fvMesh& mesh = fDMean.mesh(); volScalarField::Boundary& pBf = p.boundaryFieldRef(); forAll(mesh.boundaryMesh(), i) { const polyPatch& patch = mesh.boundaryMesh()[i]; if (isA<wallPolyPatch>(patch)) { pBf[i] = fDMean.boundaryField()[i] & (patch.faceAreas()/mag(patch.faceAreas())); } } Info<< " mag(UMean) max/min : " << max(mag(UMean)).value() << " " << min(mag(UMean)).value() << endl; Info<< " translationalT max/min : " << max(translationalT).value() << " " << min(translationalT).value() << endl; Info<< " internalT max/min : " << max(internalT).value() << " " << min(internalT).value() << endl; Info<< " overallT max/min : " << max(overallT).value() << " " << min(overallT).value() << endl; Info<< " p max/min : " << max(p).value() << " " << min(p).value() << endl; UMean.write(); translationalT.write(); internalT.write(); overallT.write(); p.write(); Info<< "dsmcFields written." << nl << endl; return true; } else { Info<< "Small value (" << min(mag(rhoNMean)) << ") found in rhoNMean field. " << "Not calculating dsmcFields to avoid division by zero." << endl; return false; } } // ************************************************************************* // |
|
Rather than add a lot of mean field reading clutter to dsmcFields it is better that these are read by the postProcess utility in the same way as is done for the other post-processing functionObjects. This simply requires the creation of a postProcess configuration file in OpenFOAM-???/etc/caseDicts/postProcessing. I have added this file in OpenFOAM-dev and OpenFOAM-4.x so now postProcess -time 0.001 -func dsmcFields works on the wedge15Ma5 case. |
|
Yeah that's a great solution, now you can at least use the functionObject in postProcess. My workaround did not even work, it always read the same timestep. |
Date Modified | Username | Field | Change |
---|---|---|---|
2017-03-13 19:07 | chrisk | New Issue | |
2017-03-13 19:39 | henry | Note Added: 0007924 | |
2017-03-13 21:51 | chrisk | File Added: dsmcFields.C | |
2017-03-13 21:51 | chrisk | Note Added: 0007926 | |
2017-03-13 21:51 | chrisk | File Added: dsmcFields-2.C | |
2017-03-13 21:57 | chrisk | Note Added: 0007927 | |
2017-03-13 22:05 | henry | Note Added: 0007928 | |
2017-03-14 12:55 | chrisk | File Added: dsmcFields-WorkAround.C | |
2017-03-14 12:55 | chrisk | Note Added: 0007929 | |
2017-03-14 15:35 | henry | Note Added: 0007930 | |
2017-03-16 11:54 | chrisk | Note Added: 0007932 | |
2017-03-16 12:00 | henry | Assigned To | => henry |
2017-03-16 12:00 | henry | Status | new => resolved |
2017-03-16 12:00 | henry | Resolution | open => fixed |
2017-03-16 12:00 | henry | Fixed in Version | => 4.x |