ATK
ATK

Reputation: 1526

Run a Fortran executable with an input file with changing variable

I have a Fortran code that reads an input file using the "namelist" feature. Now, it happens that two for the variables in namelist say x and y, are to be varied. So ultimately what I want is

    do x=1,10
       do y = 2,5
        run fortran code with the new x and y.
       end 
     end

Now, there are many other variables in my input file which is read by the namelist in Fortran. So, I am looking for some shell script that can vary that specific x and y in my input file.

My Namelist file "input.inp" is looking something like:

    &BASICS
     x = 1
     y = 2
     H0_CONST = .F.
     T0 = 293
     Ma_in = 1.2 
    &END

I basically want to run my program go.exe for multiple values of x and y. Those defined in the namelist are just the initial values plus some additional variables defined that should remain constant. My Fortran code looks after file "input.inp" and reads the namelist as:

    read(2,nml=basics, iostat=io_stat)

Upvotes: 0

Views: 1967

Answers (2)

Mark Setchell
Mark Setchell

Reputation: 208033

Here is a simple script that you can run your program with. Save it as go and then you can run your program with all the various NAMELIST files just by typing:

./go

The bash code is:

#!/bin/bash
for x in {1..10}; do
   for y in {2..5}; do

      # Generate the NAMELIST file
      { echo "&BASICS"
        echo " x=$x"
        echo " y=$y"
        echo " H0_CONST=.F."
        echo " T0=293"
        echo " Ma_in=1.2"
        echo "&END"
      } > input.inp

      # Now run your program
      YourProgram input.inp

   done
done

Before you run it the first time, you must just once, make the script executable with:

chmod +x go

Upvotes: 2

karakfa
karakfa

Reputation: 67567

you want to repeatedly substitute values in a configuration file where your program will read the inputs at each run.

you can do this with sed in place replacement in a nested for loop.

for example, for the given file

$ cat file
&basics x=1 y=1 &end

staying consistent with bash conventions, don't have any white space around the = signs.

$ for x in {1..4}; do for y in {1..2}; 
  do sed -i -r "s/x=\w+/x=$x/;s/y=\w+/y=$y/" file; 
  cat file;  # <-- here run your program instead
  done; done

&basics x=1 y=1 &end
&basics x=1 y=2 &end
&basics x=2 y=1 &end
&basics x=2 y=2 &end
&basics x=3 y=1 &end
&basics x=3 y=2 &end
&basics x=4 y=1 &end
&basics x=4 y=2 &end

instead of printing the file, you can run your program instead.

If your variables are not integers, you need to change sed matching from word to non-space. Also for the loop you have to enumerate values this time. Look at the updated script below...

$ for x in 1.1 2.2; do for y in 1.2 3.2; 
  do sed -i -r "s/x=\S+/x=$x/;s/y=\S+/y=$y/" file; 
  cat file; 
  done; done

Upvotes: 2

Related Questions