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/)
-   -   Checking dictionary in parallel (https://www.cfd-online.com/Forums/openfoam-programming-development/203222-checking-dictionary-parallel.html)

Gerry Kan June 21, 2018 04:56

Checking dictionary in parallel
 
Howdy Folks:

In my solver I will be reading from a custom system dictionary. I wanted the solver to check if the dict follows the proper dictionary format. Here is a code snippet:

Code:

        // preamble not shown

int main ( int argc, char *argv[] )  {

        // standard and default OF includes not shown

const word xyzDictName ( "xyzDict" );
IOobject xyzDictIO ( /* implementation not shown */ );

if ( !xyzDictIO.typeHeaderOk<dictionary>(true) )
    FatalErrorIn ( args.executable () )  <<
    "File " << xyzDictIO.name() << " not found in " <<
    xyzDictIO.instance() << exit (FatalError);

        // rest of code not shown

The solver compiled without warning and works fine when I run this on a single processor. For parallel runs, however, my solver will give me the following error, for some or all of the nodes:

Code:

[0]
[0]
[0] --> FOAM FATAL ERROR:
[0] File xyzDict not found in "system"
[0]
[0]
FOAM parallel run exiting
[0]
[2]
[2]
[2] --> FOAM FATAL ERROR:
[2] File xyzDict not found in "system"
[2]
[2]
FOAM parallel run exiting
[2]

I have a feeling that each instance of the solver is looking for the offending dict (xyzDict) in their respective temp directories and (logically) they could not be found because it's not there. Am I missing something, as it seems that it should be the way to check the integrity of the dictionary files.

Thanks in advance, Gerry.

jherb June 22, 2018 08:05

You can check, if the current process is running in the master process like this:
Code:

    if (Pstream::master())
    {
        // do whatever you want to do on the master
    }


Gerry Kan June 28, 2018 07:44

Hallo JH,

Thanks, but I don't think this would work because I am getting the same error message for every node. Limiting the search to the master node will not work.

Incidentally, I tried anyways (what can I lose?), but it unfortunately only confirmed my suspicion.

Gerry.

Quote:

Originally Posted by jherb (Post 696890)
You can check, if the current process is running in the master process like this:
Code:

    if (Pstream::master())
    {
        // do whatever you want to do on the master
    }



rajibroy August 22, 2019 18:59

Having the same issue with OpenFOAM-6. Did you find any solution?
Thank you in advance.

Edit: Found a solution
Print the dictionary path information using :
Code:

Info <<  <dict-name>.objectPath() << endl;
In a parallel execution case, it points to
Code:

<caseDir>/processor0/constant
, which is naturally absent in the decomposed "processor0/constant" folder. Therefore, I created a symbolic link of the dictionary from "caseDir/constant" to "caseDir/processor0/constant" folder to make it work.

I guess in the source code, it's possible to create a dictionary pointer to assign appropriate path based on serial or parallel execution. Hope somebody will find the solution helpful.

Regards,
R

dasbrot November 25, 2020 13:23

Sorry to bump this thread, but are there any news on the topic? I don't really consider the symlink method a good solution, especially since I hve the same problem in a multi-region case.

The problem is e.g. in this line where I try to read a dictionary
Code:

IOdictionary
      (
                IOobject
                (
                    "balanceParDict",
                      time().system(),
                      *this,
                      IOobject::MUST_READ_IF_MODIFIED,
                      IOobject::NO_WRITE
                )
        )

at runtime. This of course fails because time().system() equals e.g.
Code:

caseDir/processor0/system/fluid/balanceParDict
where 'fluid' is one of my regions. I tried replacing time.system() with time.caseSystem() which should at least link to
Code:

caseDir/system/fluid/balanceParDict
but instead the printed warning says
Code:

caseDir/../system/fluid/balanceParDict
not found, so somehow the command is not evaluated properly. Isn't there any method to directly access the global system directory? I also tried giving a relativ path, but this fails too, because the '../' is not evaluated properly.

Thanks a lot for any help, cheers!


For now I change it to time().constant() and created symlinks inside each processir*/constant/regionName folder which is easier than creating a new symlink inside each new time directory


All times are GMT -4. The time now is 11:05.