CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

Runtime modification of a volScalarField

Register Blogs Members List Search Today's Posts Mark Forums Read

Like Tree7Likes
  • 2 Post By mkraposhin
  • 5 Post By mkraposhin

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   August 14, 2013, 06:59
Default Runtime modification of a volScalarField
  #1
New Member
 
Daniel Leichtle
Join Date: Aug 2013
Posts: 6
Rep Power: 12
Scofield is on a distinguished road
Hey all,

I would like to modify a volScalarField called "modifyS" during runtime of a simulation. "modifyS" is a uniform field and located in the "constant" directory of my case.

In "createFields.H" I specify this field by using following IOobject definition:
----------------------
volScalarField modifyS
(
IOobject
(
"modifyS",
runTime.constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
),
mesh
);

----------------------

My problem:
If I modify "modifyS" during runtime, the modification is not read in. Even if I insert the lookup function at the beginning of the time loop, a modification is not read in:

----------------------
const volScalarField& modifyS = mesh.lookupObject<volScalarField>("modifyS");
-----------------------

Does anyone know how to modify a volScalarField during runtime?

Thanks in advance!
Regards,
Daniel
Scofield is offline   Reply With Quote

Old   August 14, 2013, 13:23
Default
  #2
Senior Member
 
mkraposhin's Avatar
 
Matvey Kraposhin
Join Date: Mar 2009
Location: Moscow, Russian Federation
Posts: 355
Rep Power: 21
mkraposhin is on a distinguished road
Quote:
Originally Posted by Scofield View Post
Hey all,

I would like to modify a volScalarField called "modifyS" during runtime of a simulation. "modifyS" is a uniform field and located in the "constant" directory of my case.

In "createFields.H" I specify this field by using following IOobject definition:
----------------------
volScalarField modifyS
(
IOobject
(
"modifyS",
runTime.constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
),
mesh
);

----------------------

My problem:
If I modify "modifyS" during runtime, the modification is not read in. Even if I insert the lookup function at the beginning of the time loop, a modification is not read in:

----------------------
const volScalarField& modifyS = mesh.lookupObject<volScalarField>("modifyS");
-----------------------

Does anyone know how to modify a volScalarField during runtime?

Thanks in advance!
Regards,
Daniel
First note.
when you are writing
----------------------
const volScalarField& modifyS = mesh.lookupObject<volScalarField>("modifyS");
-----------------------
you are not asking OpenFOAM to re-read field. This string means only: "find object of type volScalarField with the name modifyS and return constant reference to it to me"

Second note.
IOobject only defines flags for I/O, but method readIfModified() of the class regIOobject (which inherits from IOobject and inherited by volScalarField) do the task what you want.

So, you can try to insert line:
---
modifyS.readIfModified();
---

at the start of each time step:

while (runTime.run())
{
modifyS.readIfModified();
// do something else
}

Third note.
You can always check whether dictionary (field) was modified by the method modifyS.modified().
Than, you can run method modifyS.read()
See documentation here

Hope, this helped to you
mkraposhin is offline   Reply With Quote

Old   August 20, 2013, 10:49
Default
  #3
New Member
 
Daniel Leichtle
Join Date: Aug 2013
Posts: 6
Rep Power: 12
Scofield is on a distinguished road
Thanks a lot mkraposhin for your response. I really appreciate that.

Unfortunately the volScalarField "modifyS" ist still not updated when modified.
I have implemented it this way:

In createFields.H:
-------------------------------------
Info<< "Reading field modifyS\n" << endl;
volScalarField modifyS
(
IOobject
(
"modifyS",
runTime.constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
),
mesh
);

-----------------------------------

In shallowFoam.C:
----------------------------------------
...
while (runTime.run())
{
#include "readTimeControls.H"
#include "CourantNo.H"
#include "setDeltaT.H"

modifyS.readIfModified();
runTime++;
Info<< "modifyS = " << modifyS << nl << endl;
//... something else
}

-----------------------------------

I have deleted the lookup- function.
Do you or does someone else have an idea what else i can try?

I have another problem:
As soon as I define in createFields.H the IOobject "modifyS" as "MUST_READ_IF_MODIFIED", a modification of "modifyS" sometimes causes an abortion of the simulation with this error:
--------------------------------
regIOobject::readIfModified() :
Re-reading object modifyS from file "/home/BAUINFORMATIK/OpenFOAM/run/interactivity/PflegerTestModifyS/constant/modifyS"

--> FOAM FATAL IO ERROR:
cannot open file

file: /home/BAUINFORMATIK/OpenFOAM/run/interactivity/PflegerTestModifyS/constant/modifyS at line 0.

From function regIOobject::readStream()
in file db/regIOobject/regIOobjectRead.C at line 87.

FOAM exiting

----------------------------------------

Does someone know the reason for this error and why it occurs just sometimes?

Remarks:
- When I define the IOobject modifyS at the beginning of the time loop (with MUST_READ or MUST_READ_IF _MODIFIED), the modification actually works. But I also get sometimes this error that the corresponding file can't be opended. So if I can get rid of this error, I can at least use this unconventional solution.

- I have tested to modify the IOdictionary "transportProperties", and there a modification is always read in and the simulation is never stopped by an error. I don't know why it does not work for a volScalarField.

Thanks a lot in advance!
Scofield is offline   Reply With Quote

Old   August 20, 2013, 17:15
Default
  #4
Senior Member
 
mkraposhin's Avatar
 
Matvey Kraposhin
Join Date: Mar 2009
Location: Moscow, Russian Federation
Posts: 355
Rep Power: 21
mkraposhin is on a distinguished road
Hi, Scofield

By inspecting the OpenFOAM source code i found, that you cannot update volScalarField only by specifying MUST_READ_IF_MODIFIED at the construction.

The problem is that only IOdictionary class knows how to read data from file when it was modified.

More over, when object was modified, OpenFOAM object runTime reads it (by executing function ::read()) and sets the modified flag() to false.

You have three ways:

1) Use IOdictionary to store additional flags which will show that field modifyS was modified. If this flag was triggered, then, you need to re-init your field

2) Derive interface class from regIOobject and dictionary to read field when it was modified and then, substitute to volScalarField as a construction parameter

3) Derive you own field class from the GeometricField.

I will explain to you path #2

1) Create class IOfieldDictionary, which is derived from regIOobject and dictionary
Code:
class IOfieldDictionary
:
    public regIOobject,
    public dictionary
{
    const word type_;

public:

    // Redefine type name to be of the instantiated type
    virtual const word& type() const
    {
        return type_;
    }


    // Constructors

        //- Construct from ioobject and overloaded typename.
        explicit IOfieldDictionary(const IOobject& io, const word& type)
        :
            regIOobject(io),
            dictionary(readStream(type)),
            type_(type)
        {
            close();
        }



    // Member functions

        virtual bool readData(Istream& is)
        {
            is >> *this;
            
            return !is.bad();
        }

        virtual bool writeData(Ostream& os) const
        {
            dictionary::write(os, false);
            return os.good();
        }

        virtual bool write() const
        {
            return regIOobject::write();
        }
};
2) Create one object for this dictionary and second object for your field (pointer) in your createFields.H
Code:
    IOfieldDictionary modifySDict
    (
            IOobject
            (
                "modifyS",
                runTime.constant(),
                mesh,
                IOobject::MUST_READ_IF_MODIFIED,
                IOobject::NO_WRITE
            ),
            "volScalarField"
    );
    
    autoPtr<volScalarField> modifySPtr
    (
        new volScalarField
        (
            IOobject
            (
                "modifyS",
                runTime.constant(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            mesh,
            modifySDict
        )
    );
3) Monitor for the additional flag ("modified") in your field at the start of each timestep:
Code:
    while (runTime.loop())
    {
        Info<< "Time = " << runTime.timeName() << nl << endl;
        
        {
            Switch modified (modifySDict.lookup("modified"));
            
            Info << "modified" << modified << endl;
            
            if (modified)
            {
                //create a new field
                autoPtr<volScalarField> modifySPtr
                (
                    new volScalarField
                    (
                        IOobject
                        (
                            "modifyS",
                            runTime.constant(),
                            mesh,
                            IOobject::NO_READ,
                            IOobject::NO_WRITE
                        ),
                        mesh,
                        modifySDict
                    )
                );

                modified = false;

                modifySDict.set<Switch>("modified", modified);
                IOfieldDictionary(modifySDict).write();

                Info << "field was modified" << endl << modifySPtr() << endl;
            }
        }
        volScalarField& modifyS = modifySPtr();
I attached the source code for the application and test case in tar.gz

when you finished with changing of the field in modifyS, you must set flag "modified" to true:
Code:
modified        true;

dimensions      [ 0 0 0 0 0 0 0 ];

internalField   uniform 2;

boundaryField
{
    movingWall
    {
        type            zeroGradient;
    }
    fixedWalls
    {
        type            zeroGradient;
    }
    frontAndBack
    {
        type            empty;
    }
}
Attached Files
File Type: gz myIcoFoam.tar.gz (4.0 KB, 63 views)
mkraposhin is offline   Reply With Quote

Old   October 1, 2013, 09:31
Default
  #5
New Member
 
Daniel Leichtle
Join Date: Aug 2013
Posts: 6
Rep Power: 12
Scofield is on a distinguished road
Thanks a lot mkraposhin for your help. I have integrated it in my code and it works, your response was the solution for my problem. Great!

In another thread I have posted a similar problem:
http://www.cfd-online.com/Forums/ope...tml#post454451
Scofield is offline   Reply With Quote

Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
[openSmoke] libOpenSMOKE Tobi OpenFOAM Community Contributions 562 January 25, 2023 10:21
if-loop, volScalarField comparison volker OpenFOAM 7 March 6, 2020 21:03
Problems with creating a volScalarField georlade OpenFOAM Programming & Development 4 December 4, 2016 13:31
Problem in3D model processing mebinitap OpenFOAM 2 December 12, 2014 05:40
Error at runtime modification of a volScalField Scofield OpenFOAM Programming & Development 1 August 14, 2013 15:02


All times are GMT -4. The time now is 18:01.