CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   fields not auto written when stored in a HashTable (https://www.cfd-online.com/Forums/openfoam-programming-development/221452-fields-not-auto-written-when-stored-hashtable.html)

fedvasu October 17, 2019 00:40

fields not auto written when stored in a HashTable
 
Hi,

I have two data structures

Code:

PtrList<volScalarField> indScalarFields_;
HashTable<volScalarField,word> depScalarFields_;

forAll(indScalarNames_, i)
    {
        indScalarFields_.set
        (
            i,
            new volScalarField
            (       
                IOobject
                (
                    indScalarNames_[i]+"PDF",
                    mesh_.time().timeName(),
                    mesh,
                    IOobject::MUST_READ,
                    IOobject::AUTO_WRITE
                ),
                mesh             
            )
        );
    }

   
    forAll(depScalarNames_, i)
    {
        depScalarFields_.insert
        (
            depScalarNames_[i],
            volScalarField
            (       
                IOobject
                (
                    depScalarNames_[i]+"PDF",
                    mesh_.time().timeName(),
                    mesh_,
                    IOobject::NO_READ,
                    IOobject::AUTO_WRITE
                ),
                mesh_,
                dimensionedScalar(depScalarNames_[i]+"PDF", dimensionSet(0, 0, 0, 0, 0, 0, 0), 0.0)       
            )
        );
    }

The VolScalarFields in indScalarFields_ (PtrList) are witten every write timeStep but fields in depScalarFields_ are not written.

I have verified that the hashtable indeed contains correct fields and values calculated are correct.

This is quite unexpected and puzzling.

hjasak October 18, 2019 12:42

You probably have multiple fields with the same name, and your hash table is messed up.

At the moment, the error of checking in multiple fields with the same name is not flagged, but you should not do it.

You can check the contents of the database before writing - this will tell you what is going on...

fedvasu October 18, 2019 16:08

Quote:

Originally Posted by hjasak (Post 747454)
You probably have multiple fields with the same name, and your hash table is messed up.

At the moment, the error of checking in multiple fields with the same name is not flagged, but you should not do it.

You can check the contents of the database before writing - this will tell you what is going on...

Yeah I checked the db, none of the fields are in there. I have also checked that none of my fields have same name.

That is NOT a problem at all.

I have explicitly written those fields using .write(), It writes them just fine.

hjasak November 13, 2019 07:21

Well:
- when you insert a pointer to a field to the PtrList, it will take the field ptr as it stands and put it in. All is well. Field is registered in db when you made a pointer and never tampered with


- When you insert a field into a HashTable - as opposed to the HashPtrTable - it will MAKE A COPY. The first (given) field is registered; you make the copy, try to register it, but fail, because there is already a field under the same name. Then you delete the first one, but you lost the position in db (the copied field was not registered) for the one that is actually in HashTable and on autoWrite it is not written.

So, I was right. How to fix it:
- use a HashPtrTable and all will be well - see above.
- create the first field without registering (there is a construcvtor flag) and then the second field willl register
- use a proper move construvtor for a field if possible. I did not look at the code; this kind of thing should happen quite often...

(temper, temper...)


Hrv

olesen November 29, 2019 10:36

@Hrv: A good succinct explanation!

Another possibility would be to just put everything onto the objectRegistry for storage and lookup (since it is also just a HashPtrTable anyhow), but this might start being too complicated for a less experienced user.

fedvasu December 3, 2019 15:28

Quote:

Originally Posted by hjasak (Post 749666)
Well:
- when you insert a pointer to a field to the PtrList, it will take the field ptr as it stands and put it in. All is well. Field is registered in db when you made a pointer and never tampered with


- When you insert a field into a HashTable - as opposed to the HashPtrTable - it will MAKE A COPY. The first (given) field is registered; you make the copy, try to register it, but fail, because there is already a field under the same name. Then you delete the first one, but you lost the position in db (the copied field was not registered) for the one that is actually in HashTable and on autoWrite it is not written.

So, I was right. How to fix it:
- use a HashPtrTable and all will be well - see above.
- create the first field without registering (there is a construcvtor flag) and then the second field willl register
- use a proper move construvtor for a field if possible. I did not look at the code; this kind of thing should happen quite often...

(temper, temper...)


Hrv

Thanks for the clear explanation. I will use HashPtrTable from here on.


All times are GMT -4. The time now is 00:33.