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

Accessing controlDict variables in BASH run script

Register Blogs Community New Posts Updated Threads Search

Like Tree5Likes
  • 1 Post By Tobermory
  • 1 Post By olesen
  • 2 Post By olesen
  • 1 Post By Tobermory

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   October 16, 2020, 07:01
Default Accessing controlDict variables in BASH run script
  #1
Member
 
Callum Guy
Join Date: Dec 2019
Location: Scotland
Posts: 44
Rep Power: 7
CallumG is on a distinguished road
Hi Foamers,

I would just like to know how to access a variable from the controlDict while writing a BASH runscript. I'm trying to automate a restart in my case should the simmulation fail.

I essentially want to do something like:



if ( /prossessor*/ "endTime" doesn't exist ):
restart solver
else:
post-process


so hence would need access to the "endTime" variable.

Thanks in advance for any help!!

Cheers
Callum
CallumG is offline   Reply With Quote

Old   October 16, 2020, 07:42
Default
  #2
Senior Member
 
Join Date: Apr 2020
Location: UK
Posts: 747
Rep Power: 14
Tobermory will become famous soon enough
There are a bunch of shell utilities that you can employ to parse text files. The following would strip out the value of the "stopAt" parameter from controlDict; you should be able to use something like this to do what you need.

Code:
#!/bin/bash
val=`grep stopAt system/controlDict | sed 's/;//' | tr -s " " | cut -d" " -f2`
echo $val
The grep command strips out any lines containing the word "stopAt", the sed command gets rid of the ";" at the end of the line, the tr command squeezes out excess spaces and the cut command splits the line into separate fields using a space as the separator andd chooses the second field. All of this is enclosed in the backwards quotes (or whatever they are called) which means execute the command and return the value ... this value is then set to variable val.

Good luck!
Tobermory is offline   Reply With Quote

Old   October 16, 2020, 07:50
Default
  #3
Member
 
Callum Guy
Join Date: Dec 2019
Location: Scotland
Posts: 44
Rep Power: 7
CallumG is on a distinguished road
Awesome! Thanks Tobermory!

I was hoping for an elogant OpenFOAM runTime function of some sort but the brute force approach will work nicely! :-)

Cheers!
CallumG is offline   Reply With Quote

Old   October 16, 2020, 07:55
Default
  #4
Senior Member
 
Join Date: Apr 2020
Location: UK
Posts: 747
Rep Power: 14
Tobermory will become famous soon enough
Nae bother. It occurs to me that you are trying to look at the endTime parameter and not the stopAt parameter. This might appear to be a pain since there are usually two lines with endTime in them, viz:

Code:
stopAt          endTime;
endTime         10;
You can get around that by adding a "grep -v" command to strip out the one with a semicolon at the end:

Code:
val=`grep endTime system/controlDict | grep -v "endTime;" | sed 's/;//' | tr -s " " | cut -d" " -f2`
etc. Again, good luck.
PositronCascade likes this.
Tobermory is offline   Reply With Quote

Old   October 16, 2020, 07:58
Default
  #5
Member
 
Callum Guy
Join Date: Dec 2019
Location: Scotland
Posts: 44
Rep Power: 7
CallumG is on a distinguished road
Quite right you are, I was just dealing with that as you posted!!

Should do the trick now I'm sure.

Cheers again.
CallumG is offline   Reply With Quote

Old   October 16, 2020, 09:16
Default
  #6
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by Tobermory View Post
Nae bother. It occurs to me that you are trying to look at the endTime parameter and not the stopAt parameter. This might appear to be a pain since there are usually two lines with endTime in them, viz:

Code:
stopAt          endTime;
endTime         10;
You can get around that by adding a "grep -v" command to strip out the one with a semicolon at the end:

Code:
val=`grep endTime system/controlDict | grep -v "endTime;" | sed 's/;//' | tr -s " " | cut -d" " -f2`
etc. Again, good luck.

In general, you might consider leveraging OpenFOAM utilities as well, since it is quite possible that you otherwise miss includes or pickup other things.

For example,
Code:
#include "myTimeControls"

...

stopAt          endTime;
// endTime         500;
endTime         20;
...
endTime         100;
You can handle the above input with the following
Code:
if endTime=$(foamDictionary -value -entry endTime system/controlDict 2>/dev/null)
then
    echo "endTime was $endTime"
fi



Another convenient command is foamListTimes
Code:
latestTime=$(foamListTimes -latestTime)
Can also use the -processor option to list times in the processor folder(s).
Tobermory likes this.
olesen is offline   Reply With Quote

Old   October 16, 2020, 10:03
Default
  #7
Member
 
Callum Guy
Join Date: Dec 2019
Location: Scotland
Posts: 44
Rep Power: 7
CallumG is on a distinguished road
Thanks Olesen,

very useful!

So am I right to use something like:

Code:
endTime = $(foamDictionary -value -entry endTime system/controlDict)
directory = "./processor0/"

if [ "$(ls -A $directory$endTime)" ]; then
# post-process
else
# do other stuff
fi
I'm a little unsure of the additional "2>/dev/null" argument. Could you explain it for me?

Thanks again!

Callum
CallumG is offline   Reply With Quote

Old   October 16, 2020, 10:56
Default
  #8
Senior Member
 
Join Date: Apr 2020
Location: UK
Posts: 747
Rep Power: 14
Tobermory will become famous soon enough
Very nice Olesen - I should try use those more often, but often I just write my own python or bash scripts to improve my own programming skills.

Callum - the 2>/dev/null sends stderr (i.e. any error messages) into the void (/dev/null), ie prevents them being written to screen.
Tobermory is offline   Reply With Quote

Old   October 17, 2020, 10:54
Default
  #9
Senior Member
 
Join Date: Apr 2020
Location: UK
Posts: 747
Rep Power: 14
Tobermory will become famous soon enough
It's funny, since reading your post Olesen, I've used foamListTimes in 3 differenat applications! Just shows how useful this forum can be, to seed new ideas.
Tobermory is offline   Reply With Quote

Old   October 19, 2020, 06:04
Default
  #10
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by Tobermory View Post
It's funny, since reading your post Olesen, I've used foamListTimes in 3 differenat applications! Just shows how useful this forum can be, to seed new ideas.

The -rm option for foamListTimes is also fairly convenient to clean out old directories. Previously (when we had a really, really slow) NFS system, I had an adjusted version with -bg (background) option that would avoid some of the lag by doing the following:
  1. rename the directories from time1, time2... to .stagedDeletion-time1, .stagedDelete-time2... The renaming is almost instantaneous, and by renaming to "dot" files, they are hidden from normal view and appear as if they are gone while completing the rest.
  2. fork and exit (ie, continue foamListTimes as a background process)
  3. recursive removal of the ".stagedDeletion*" directories. This can take some time, but since it happens in the background, isn't really too annoying.
I never pushed this as a patch anywhere (not even sure where the code is anymore) , but it could be something interesting if someone here feels like doing a bit of coding. Probably have to ignore the -bg option on Windows, but otherwise fairly straightforward to code. Since the utility only runs in serial, doesn't matter if you use a vfork() or a fork().


Sound like something fun to code up?
olesen is offline   Reply With Quote

Old   October 19, 2020, 06:14
Default
  #11
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by CallumG View Post
Thanks Olesen,

very useful!

So am I right to use something like:

Code:
endTime = $(foamDictionary -value -entry endTime system/controlDict)
directory = "./processor0/"

if [ "$(ls -A $directory$endTime)" ]; then
# post-process
else
# do other stuff
fi
I'm a little unsure of the additional "2>/dev/null" argument. Could you explain it for me?

Thanks again!

Callum

Tobermory already mentioned the meaning of the stderr redirect. In your case, you should also take advantage of the return code to handle failure. Also not sure why you would use "ls" instead of just checking the directory existence directly.
Possible rewrite:

Code:
unset hasEndTime
procDir="processor0"

if endTime=$(foamDictionary -value -entry endTime system/controlDict 2>/dev/null)
then
    if [ -d "$procDir" ] && [ -d "$procDir/$endTime" ]
    then
        hasEndTime="parallel"
    elif [ -d "$endTime" ]
    then
         hasEndTime="serial"
    fi
 else
    echo "Error: failed to obtain endTime .. stopping"
    exit 1

fi
 
# Can check serial/parallel or unset, or simply check anything


if [ -n "$hasEndTime" ]
then
# post-process
else
# do other stuff
fi
I split out the checks, since you might want to have scripts that also work with serial runs etc.
CallumG and Tobermory like this.
olesen is offline   Reply With Quote

Old   October 19, 2020, 06:19
Default
  #12
Member
 
Callum Guy
Join Date: Dec 2019
Location: Scotland
Posts: 44
Rep Power: 7
CallumG is on a distinguished road
I have a question regarding the $(foamListTimes -latestTime) command.

I'm trying to use it to store the latest time in a variable such that I can change the name of the log file for my solver to log.solver$latestTime and hence, OF will allow me to restart the solver after a crash. However, I dont seem to be getting a value assigned to it. My code looks something like this:

Code:
endTime=$(foamDictionary -value -entry endTime system/controlDict)
directory="./processor0/"

if [ "$(ls -A $directory 2>/dev/null)" ]; then
latestTime=$(foamListTimes -latestTime) mv log.solver log.solver$latestTime runParallel solver
else
// mesh // decompose // etc etc...
fi
If I manually stop the solve, and try to print the $latestTime variable nothing is assigned to it? Any help guys?

Cheers
Callum
CallumG is offline   Reply With Quote

Old   October 19, 2020, 06:25
Default
  #13
Member
 
Callum Guy
Join Date: Dec 2019
Location: Scotland
Posts: 44
Rep Power: 7
CallumG is on a distinguished road
Also thanks for this again Olesen, you are dragging my BASH scripting kicking and screaming upto standard! Very much appreciated!
CallumG is offline   Reply With Quote

Old   October 19, 2020, 06:40
Default
  #14
Senior Member
 
Join Date: Apr 2020
Location: UK
Posts: 747
Rep Power: 14
Tobermory will become famous soon enough
Is it because you are running a parallel run? Remember you need the -processor flag to look in the processorX folders, eg:

Code:
latestTime=$(foamListTimes -latestTime -processor)
CallumG likes this.
Tobermory is offline   Reply With Quote

Old   October 19, 2020, 06:46
Default
  #15
Member
 
Callum Guy
Join Date: Dec 2019
Location: Scotland
Posts: 44
Rep Power: 7
CallumG is on a distinguished road
BINGO!

Thanks again Tobermory! I owe you a drink! :-)

Cheers
Callum
CallumG is offline   Reply With Quote

Old   October 19, 2020, 09:16
Default
  #16
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by CallumG View Post
I have a question regarding the $(foamListTimes -latestTime) command.

I'm trying to use it to store the latest time in a variable such that I can change the name of the log file for my solver to log.solver$latestTime and hence, OF will allow me to restart the solver after a crash. However, I dont seem to be getting a value assigned to it. My code looks something like this:

Code:
endTime=$(foamDictionary -value -entry endTime system/controlDict)
directory="./processor0/"

if [ "$(ls -A $directory 2>/dev/null)" ]; then
latestTime=$(foamListTimes -latestTime) mv log.solver log.solver$latestTime runParallel solver
else
// mesh // decompose // etc etc...
fi
If I manually stop the solve, and try to print the $latestTime variable nothing is assigned to it? Any help guys?

Cheers
Callum

As a gentle reminder, look at what foamListTimes -help splits out. There should be a -processor option, which I think will make sense now. BTW: the 'ls -A' still continues to be a very ugly (bad) way to check for the existence of a directory.
olesen is offline   Reply With Quote

Old   October 19, 2020, 09:43
Default
  #17
Member
 
Callum Guy
Join Date: Dec 2019
Location: Scotland
Posts: 44
Rep Power: 7
CallumG is on a distinguished road
That's fair Olesen, I accept your critisism - an oversight on my part!

I'm sure you can recall when you first ventured into the world of open source code etc, I bet you felt similar in that what seemed so obvious and easy to others never seemed so for you. Especially for us who have no prior experience in computing (I'm a mechanical engineer). It's a lot of information to try and assimilate, and people are destined to ask similar questions in the future. Hopefully, I can pay it forward!

As for the 'ls -A' I have indeed tidied that up now. Thanks to you and Tobermory my script is now as functional as it is beautiful! :-)

Thanks again both!
CallumG 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
[swak4Foam] How to define boundary condition variables by using previosly defined variables? pawlo OpenFOAM Community Contributions 8 September 13, 2020 12:37
Running OpenFOAM case through shell script (bash) ilaj OpenFOAM Programming & Development 2 January 28, 2020 14:14
How to write the Ansys lic usage Bash script from Windows machine mg.mithun Main CFD Forum 0 November 28, 2019 10:01
Working directory via command line Luiz CFX 4 March 6, 2011 21:02
How to run PMOVLINK script? Serkan Cetin Siemens 1 May 1, 2003 13:54


All times are GMT -4. The time now is 21:34.