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

How to create a field without reading from 0 directroy

Register Blogs Community New Posts Updated Threads Search

Like Tree8Likes
  • 2 Post By adhiraj
  • 2 Post By Tobermory
  • 1 Post By olesen
  • 1 Post By olesen
  • 2 Post By olesen

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   June 25, 2023, 22:49
Default How to create a field without reading from 0 directroy
  #1
Senior Member
 
NotOverUnderated's Avatar
 
ONESP-RO
Join Date: Feb 2021
Location: Somwhere on Planet Earth
Posts: 127
Rep Power: 5
NotOverUnderated is on a distinguished road
Hello,

I have created a volScalarField using the following:

Code:
      volScalarField X
        (
            IOobject
            (
                "X",
                runTime.timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            mesh
        );

The code compiles fine, but when I run it, I get this error message:

Code:
Create time

Create mesh for time = 0



--> FOAM FATAL ERROR: (openfoam-2112 patch=220610)
cannot find file "/tmp/test/case/0/X"

    From virtual Foam::autoPtr<Foam::ISstream> Foam::fileOperations::uncollatedFileOperation::readStream(Foam::regIOobject&, const Foam::fileName&, const Foam::word&, bool) const
    in file global/fileOperations/uncollatedFileOperation/uncollatedFileOperation.C at line 542.

FOAM exiting
I have used IOobject::NO_READ so why does it complain about X not present in 0 directory?

Thank you
NotOverUnderated is offline   Reply With Quote

Old   June 26, 2023, 07:37
Default
  #2
Senior Member
 
Adhiraj
Join Date: Sep 2010
Location: Karnataka, India
Posts: 187
Rep Power: 15
adhiraj is on a distinguished road
Does something like this work?
Code:
volScalarField X
(
    IOobject
    (
        "X",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
    mesh,
    dimensionedScalar("Z", dimless, 0.0)
);
adhiraj is offline   Reply With Quote

Old   June 26, 2023, 13:37
Default
  #3
Senior Member
 
NotOverUnderated's Avatar
 
ONESP-RO
Join Date: Feb 2021
Location: Somwhere on Planet Earth
Posts: 127
Rep Power: 5
NotOverUnderated is on a distinguished road
Quote:
Originally Posted by adhiraj View Post
Does something like this work?
Code:
volScalarField X
(
    IOobject
    (
        "X",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
    mesh,
    dimensionedScalar("Z", dimless, 0.0)
);
That works! Thank you.

I wonder why does this work? could you please elaborate and explain why NO_READ has no effect?
NotOverUnderated is offline   Reply With Quote

Old   June 27, 2023, 03:38
Default
  #4
Senior Member
 
Join Date: Apr 2020
Location: UK
Posts: 668
Rep Power: 14
Tobermory will become famous soon enough
Agreed that this is misleading, but the field has to be initialised with something. The TLDR version is that the original constructor that you used is the "READ constructor" for a field, and will try read from file regardless of the NO_READ flag; the "corrected" constructor is the one to use if you do not want to read from file, but in that case you have to supply the initialisation data for the field.

If you want to see the detail, read on.

In your code, you have defined a new volScalarField, which is a templated type of GemetricField. For the constructor, you passed an IOobject and a mesh, i.e. you used the constructor (line 366 in https://cpp.openfoam.org/v8/Geometri..._source.html):

Code:
         //- Construct and read given IOobject
         GeometricField
         (
             const IOobject&,
             const Mesh&
         );
which is defined on line 342 of https://cpp.openfoam.org/v8/Geometri...8C_source.html as:

Code:
 template<class Type, template<class> class PatchField, class GeoMesh>
 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
 (
     const IOobject& io,
     const Mesh& mesh
 )
 :
     Internal(io, mesh, dimless, false),
     timeIndex_(this->time().timeIndex()),
     field0Ptr_(nullptr),
     fieldPrevIterPtr_(nullptr),
     boundaryField_(mesh.boundary())
 {
     readFields();
 
    ... etc - I pruned out some of the lines here
     }
 }
Note the readFields() call, without any checking of the read flag. This readFields() function is defined on line 72 of GeometricField.C, and constructs an IOdictionary and calls upon the readFields() function on line 48 to read in the data. This is why your original code crashed.


Let's now look at the "corrected" constructor, i.e. the one that works for you. This uses the constructor at line 327 of GeometricField.H:
Code:
         //- Constructor given IOobject, mesh, dimensioned<Type>
         //  and patch field type.
         GeometricField
         (
             const IOobject&,
             const Mesh&,
             const dimensioned<Type>&,
             const word& patchFieldType=PatchField<Type>::calculatedType()
         );
which is defined on line 239 of GeometricField.C as:
Code:
 template<class Type, template<class> class PatchField, class GeoMesh>
 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
 (
     const IOobject& io,
     const Mesh& mesh,
     const dimensioned<Type>& dt,
     const word& patchFieldType
 )
 :
     Internal(io, mesh, dt, false),
     timeIndex_(this->time().timeIndex()),
     field0Ptr_(nullptr),
     fieldPrevIterPtr_(nullptr),
     boundaryField_(mesh.boundary(), *this, patchFieldType)
 {
     if (debug)
     {
         InfoInFunction << "Creating temporary" << endl << this->info() << endl;
     }
 
     boundaryField_ == dt.value();
 
     readIfPresent();
 }
Note that even though the initialisation data that you pass the constructor (dt) is used to fill the field, a call is still made to readIfPresent(). This means that your initialisation data will be overwritten by the contents of the file, if the file is present ... UNLESS you use the NO_READ flag, in which case the read from file is skipped.

Hope this helps!
Tobermory is offline   Reply With Quote

Old   June 27, 2023, 04:34
Smile Great explanation!
  #5
Senior Member
 
NotOverUnderated's Avatar
 
ONESP-RO
Join Date: Feb 2021
Location: Somwhere on Planet Earth
Posts: 127
Rep Power: 5
NotOverUnderated is on a distinguished road
Quote:
Originally Posted by Tobermory View Post
Agreed that this is misleading, but the field has to be initialised with something. The TLDR version is that the original constructor that you used is the "READ constructor" for a field, and will try read from file regardless of the NO_READ flag; the "corrected" constructor is the one to use if you do not want to read from file, but in that case you have to supply the initialisation data for the field.

If you want to see the detail, read on.

In your code, you have defined a new volScalarField, which is a templated type of GemetricField. For the constructor, you passed an IOobject and a mesh, i.e. you used the constructor (line 366 in https://cpp.openfoam.org/v8/Geometri..._source.html):

Code:
         //- Construct and read given IOobject
         GeometricField
         (
             const IOobject&,
             const Mesh&
         );
which is defined on line 342 of https://cpp.openfoam.org/v8/Geometri...8C_source.html as:

Code:
 template<class Type, template<class> class PatchField, class GeoMesh>
 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
 (
     const IOobject& io,
     const Mesh& mesh
 )
 :
     Internal(io, mesh, dimless, false),
     timeIndex_(this->time().timeIndex()),
     field0Ptr_(nullptr),
     fieldPrevIterPtr_(nullptr),
     boundaryField_(mesh.boundary())
 {
     readFields();
 
    ... etc - I pruned out some of the lines here
     }
 }
Note the readFields() call, without any checking of the read flag. This readFields() function is defined on line 72 of GeometricField.C, and constructs an IOdictionary and calls upon the readFields() function on line 48 to read in the data. This is why your original code crashed.


Let's now look at the "corrected" constructor, i.e. the one that works for you. This uses the constructor at line 327 of GeometricField.H:
Code:
         //- Constructor given IOobject, mesh, dimensioned<Type>
         //  and patch field type.
         GeometricField
         (
             const IOobject&,
             const Mesh&,
             const dimensioned<Type>&,
             const word& patchFieldType=PatchField<Type>::calculatedType()
         );
which is defined on line 239 of GeometricField.C as:
Code:
 template<class Type, template<class> class PatchField, class GeoMesh>
 Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
 (
     const IOobject& io,
     const Mesh& mesh,
     const dimensioned<Type>& dt,
     const word& patchFieldType
 )
 :
     Internal(io, mesh, dt, false),
     timeIndex_(this->time().timeIndex()),
     field0Ptr_(nullptr),
     fieldPrevIterPtr_(nullptr),
     boundaryField_(mesh.boundary(), *this, patchFieldType)
 {
     if (debug)
     {
         InfoInFunction << "Creating temporary" << endl << this->info() << endl;
     }
 
     boundaryField_ == dt.value();
 
     readIfPresent();
 }
Note that even though the initialisation data that you pass the constructor (dt) is used to fill the field, a call is still made to readIfPresent(). This means that your initialisation data will be overwritten by the contents of the file, if the file is present ... UNLESS you use the NO_READ flag, in which case the read from file is skipped.

Hope this helps!
Many thanks for this detailed explanation.
NotOverUnderated is offline   Reply With Quote

Old   June 27, 2023, 08:49
Default
  #6
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,686
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by NotOverUnderated View Post
That works! Thank you.

I wonder why does this work? could you please elaborate and explain why NO_READ has no effect?

In the openfoam.com version you should at least have seen a warning message:
Code:
read option IOobject::MUST_READ or MUST_READ_IF_MODIFIED  
suggests that a read constructor for field " field-name
would be more appropriate."

If you want to create without initialization, you should at least provide the dimensionSet (eg, length, velocity etc) so that later assignments make sense.
NotOverUnderated likes this.
olesen is offline   Reply With Quote

Old   June 27, 2023, 16:07
Default
  #7
Senior Member
 
NotOverUnderated's Avatar
 
ONESP-RO
Join Date: Feb 2021
Location: Somwhere on Planet Earth
Posts: 127
Rep Power: 5
NotOverUnderated is on a distinguished road
Quote:
Originally Posted by olesen View Post
In the openfoam.com version you should at least have seen a warning message:
Code:
read option IOobject::MUST_READ or MUST_READ_IF_MODIFIED  
suggests that a read constructor for field " field-name
would be more appropriate."
I am using OpenFOAM v2112 but I do not see that warning message. I have tried with v2212 but no warning message as well.
NotOverUnderated is offline   Reply With Quote

Old   June 28, 2023, 06:03
Default
  #8
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,686
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by NotOverUnderated View Post
I am using OpenFOAM v2112 but I do not see that warning message. I have tried with v2212 but no warning message as well.

Yes you are correct, the warning message are for some of the other constructors, not for the one that you are using. It actually does go off and attempt to read in fields regardless of the IOobject read setting.


The best advice (and the conclusion that you've already reached) is not to use that particular constructor. Aside from the reading issue, the missing dimensions are a bit of a showstopper. Still undecided if it is worth raising an issue for this behaviour. I'll leave that up to you.
NotOverUnderated likes this.
olesen is offline   Reply With Quote

Old   June 28, 2023, 13:03
Default
  #9
Senior Member
 
NotOverUnderated's Avatar
 
ONESP-RO
Join Date: Feb 2021
Location: Somwhere on Planet Earth
Posts: 127
Rep Power: 5
NotOverUnderated is on a distinguished road
Quote:
Originally Posted by olesen View Post
Yes you are correct, the warning message are for some of the other constructors, not for the one that you are using. It actually does go off and attempt to read in fields regardless of the IOobject read setting.


The best advice (and the conclusion that you've already reached) is not to use that particular constructor. Aside from the reading issue, the missing dimensions are a bit of a showstopper. Still undecided if it is worth raising an issue for this behaviour. I'll leave that up to you.
I have seen many online tutorials use the first constructor (without dimensions). My OpenFOAM programming skills are relatively basic and I often find myself forgetting to define these dimensions. While I can't speak for everyone, I personally feel that a warning message would serve as a useful reminder to avoid confusion.

Thank you
NotOverUnderated is offline   Reply With Quote

Old   June 29, 2023, 03:05
Default
  #10
Senior Member
 
Join Date: Apr 2020
Location: UK
Posts: 668
Rep Power: 14
Tobermory will become famous soon enough
Quote:
Originally Posted by olesen View Post
Still undecided if it is worth raising an issue for this behaviour.
As you pointed out Mark - it's working as intended, but also agreed that it's a little confusing. I think the best way to make this more transparent would be to simply ammend the description of the constructor in the header file, to state that this is the read constructor (OF refers to it like this in the warning message that you highlighted), or something similar.
Tobermory is offline   Reply With Quote

Old   June 30, 2023, 03:54
Default
  #11
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,686
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by Tobermory View Post
As you pointed out Mark - it's working as intended, but also agreed that it's a little confusing. I think the best way to make this more transparent would be to simply ammend the description of the constructor in the header file, to state that this is the read constructor (OF refers to it like this in the warning message that you highlighted), or something similar.

Opened an issue: https://develop.openfoam.com/Develop.../-/issues/2926 can add comments/preferences/ideas there.
olesen is offline   Reply With Quote

Reply


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
Illegal cell label -1, fluent3DMeshToFoam BenGher OpenFOAM 7 October 10, 2023 00:02
[Commercial meshers] Problem converting fluent mesh vinz OpenFOAM Meshing & Mesh Conversion 28 October 12, 2015 06:37
[General] How to create an additional vector with {Field 4, Field 5, Field 6} Bombacar ParaView 1 August 15, 2015 18:05
[Commercial meshers] fluentMeshToFoam multidomain mesh conversion problem Attesz OpenFOAM Meshing & Mesh Conversion 12 May 2, 2013 10:52
Actuator disk model audrich FLUENT 0 September 21, 2009 07:06


All times are GMT -4. The time now is 19:28.