fprintf() C variables into FORTRAN input file format ???

Discussion in 'C Programming' started by google, Apr 10, 2004.

  1. google

    google Guest

    first, a little background...

    i have a C program which preprocesses some data, and then outputs the
    results into a text file. that text file, in turn, is used as input
    to a FORTRAN computational fluid dynamics (CFD) program. the FORTRAN
    program goes to work on the provided data, and outputs a text file
    which i read back in with another C program to postprocess the data
    and analyze the results of the CFD run.

    now on to the problem. the input file to the FORTRAN CFD program is
    in the following format (which may look familiar to folks well versed
    in FORTRAN, which i'm not):
    (ronin)$ cat boundedmatrix.in
    1.0D0 ! Ratio
    1.5D0 ! AXMAX
    1 ! NPNAX
    1D-1 ! B
    0.5D0 ! GAM
    18 ! NKMAX
    1.7D0 ! EPS
    -1 ! NP
    0.6283D0 ! LAM (wavelength)
    1.50D0 ! MRR (real part of the refractive index)
    0.02D0 ! MRI (imag part of the refractive index)
    0.00001D0 ! DDELT
    181 ! NPNA (number of angles)
    2 ! NDGS

    the format of the FORTRAN input parameters, as you can see, carries
    the precision of the value with it. e.g., 1.0D0 is a double precision
    value X 10^0. and, 1D-1 is a double precision value X 10^-1.

    now then, i'm a complete novice when it comes to FORTRAN, and denoting
    the value precision in the input file in this way seems, to this C
    programmer, to be a little odd. but nevertheless that's the way it
    is.

    does anyone have any ideas on how i might get my fprintf()'s to output
    these kinds of values without a lot of gymnastics? i've taken a
    couple of simplistic runs at it but i haven't gotten anywhere except
    really-frustrated-ville. it appears that it should be easy to do but
    i haven't found a clever way yet. of course i know ahead of time
    which of my C variables are double precision and so forth. for that
    matter i know a priori which variables the FORTRAN program are
    expected to be in double precision.

    note that it is no way possible for me to modify the FORTRAN program,
    it's a NSF-sourced CFD code and if i touch it i can look forward to
    about 10 years of verification tests. each CFD run is taking about 6
    hours on a 512 processor SGI Origin box as it is. so the solution can
    not include "tweaking" the FORTRAN code in any way. i have to treat
    the CFD program as an immutable black box.

    ideas, thoughts, catalysts, FORTRAN-conversion.c source, hate mail,
    etc are all welcome.

    thanks
    jim
    google, Apr 10, 2004
    #1
    1. Advertising

  2. google

    Malcolm Guest

    "google" <> wrote in message
    >
    > 1.0D0 is a double precision value X 10^0. and, 1D-1 is a double
    > precision value X 10^-1.
    >
    > does anyone have any ideas on how i might get my fprintf()'s to
    > output these kinds of values without a lot of gymnastics?
    >

    All you need is a function

    void dbltofortan(FILE *fpout, double x)
    {
    double lg = log10(x);
    fprintf(fp, "%gD%d", x / pow(10, floor(lg)), floor(lg));
    }

    Hope this is right (untested).
    Malcolm, Apr 11, 2004
    #2
    1. Advertising

  3. On Sat, 10 Apr 2004, google wrote:
    >
    > now on to the problem. the input file to the FORTRAN CFD program is
    > in the following format (which may look familiar to folks well versed
    > in FORTRAN, which i'm not):
    > (ronin)$ cat boundedmatrix.in
    > 1.0D0 ! Ratio
    > 1.5D0 ! AXMAX
    > 1 ! NPNAX
    > 1D-1 ! B
    > 0.5D0 ! GAM

    <snip>

    > the format of the FORTRAN input parameters, as you can see, carries
    > the precision of the value with it. e.g., 1.0D0 is a double precision
    > value X 10^0. and, 1D-1 is a double precision value X 10^-1.


    The 'D', I suppose, represents significant figures somehow? That is,
    is the value 0.1D0 different from the value 1D-1? If so, then I think
    you'll have to cope with the fact that C's "float" and "double" values
    don't have any concept of "significant figures," so you're going to
    lose some information somewhere.
    If 0.1D0 and 1D-1 are in fact the same value, then you should just
    be able to write something like this, to append "D0" to the end of
    each floating-point value you print:

    #include <stdio.h>

    int main(void)
    {
    double fieldval = 4.52;
    const char *fieldname = "FOO";

    char buffer[20];
    sprintf(buffer, "%gD0", fieldval);
    printf("%-20s! %s\n", buffer, fieldname);
    return 0;
    }

    Does this solve your problem?

    HTH,
    -Arthur
    Arthur J. O'Dwyer, Apr 11, 2004
    #3
  4. On Sat, 10 Apr 2004 19:40:40 -0400 (EDT), "Arthur J. O'Dwyer"
    <> wrote:

    >
    >On Sat, 10 Apr 2004, google wrote:
    >>
    >> now on to the problem. the input file to the FORTRAN CFD program is
    >> in the following format (which may look familiar to folks well versed
    >> in FORTRAN, which i'm not):
    >> (ronin)$ cat boundedmatrix.in
    >> 1.0D0 ! Ratio
    >> 1.5D0 ! AXMAX
    >> 1 ! NPNAX
    >> 1D-1 ! B
    >> 0.5D0 ! GAM

    ><snip>
    >
    >> the format of the FORTRAN input parameters, as you can see, carries
    >> the precision of the value with it. e.g., 1.0D0 is a double precision
    >> value X 10^0. and, 1D-1 is a double precision value X 10^-1.

    >
    > The 'D', I suppose, represents significant figures somehow? That is,
    >is the value 0.1D0 different from the value 1D-1? If so, then I think
    >you'll have to cope with the fact that C's "float" and "double" values
    >don't have any concept of "significant figures," so you're going to
    >lose some information somewhere.
    > If 0.1D0 and 1D-1 are in fact the same value, then you should just
    >be able to write something like this, to append "D0" to the end of
    >each floating-point value you print:
    >
    > #include <stdio.h>
    >
    > int main(void)
    > {
    > double fieldval = 4.52;
    > const char *fieldname = "FOO";
    >
    > char buffer[20];
    > sprintf(buffer, "%gD0", fieldval);
    > printf("%-20s! %s\n", buffer, fieldname);
    > return 0;
    > }
    >
    >Does this solve your problem?
    >
    >HTH,
    >-Arthur

    If your values will have a large range of exponents (rather than the
    small range of -1 to 0 in the sample), use the %E format specification
    with sprintf and then change the 'E' to 'D' in the string before
    writing it to the file. The width and precision modifiers can provide
    some additional control.


    <<Remove the del for email>>
    Barry Schwarz, Apr 11, 2004
    #4
  5. google

    Tim Prince Guest

    "google" <> wrote in message
    news:...
    > first, a little background...
    >
    > i have a C program which preprocesses some data, and then outputs the
    > results into a text file. that text file, in turn, is used as input
    > to a FORTRAN computational fluid dynamics (CFD) program. the FORTRAN
    > program goes to work on the provided data, and outputs a text file
    > which i read back in with another C program to postprocess the data
    > and analyze the results of the CFD run.
    >
    > now on to the problem. the input file to the FORTRAN CFD program is
    > in the following format (which may look familiar to folks well versed
    > in FORTRAN, which i'm not):
    > (ronin)$ cat boundedmatrix.in
    > 1.0D0 ! Ratio
    > 1.5D0 ! AXMAX
    > 1 ! NPNAX
    > 1D-1 ! B
    > 0.5D0 ! GAM
    > 18 ! NKMAX
    > 1.7D0 ! EPS
    > -1 ! NP
    > 0.6283D0 ! LAM (wavelength)
    > 1.50D0 ! MRR (real part of the refractive index)
    > 0.02D0 ! MRI (imag part of the refractive index)
    > 0.00001D0 ! DDELT
    > 181 ! NPNA (number of angles)
    > 2 ! NDGS
    >
    > the format of the FORTRAN input parameters, as you can see, carries
    > the precision of the value with it. e.g., 1.0D0 is a double precision
    > value X 10^0. and, 1D-1 is a double precision value X 10^-1.
    >
    > now then, i'm a complete novice when it comes to FORTRAN, and denoting
    > the value precision in the input file in this way seems, to this C
    > programmer, to be a little odd. but nevertheless that's the way it
    > is.
    >
    > does anyone have any ideas on how i might get my fprintf()'s to output
    > these kinds of values without a lot of gymnastics? i've taken a
    > couple of simplistic runs at it but i haven't gotten anywhere except
    > really-frustrated-ville. it appears that it should be easy to do but
    > i haven't found a clever way yet. of course i know ahead of time
    > which of my C variables are double precision and so forth. for that
    > matter i know a priori which variables the FORTRAN program are
    > expected to be in double precision.
    >
    > note that it is no way possible for me to modify the FORTRAN program,
    > it's a NSF-sourced CFD code and if i touch it i can look forward to
    > about 10 years of verification tests. each CFD run is taking about 6
    > hours on a 512 processor SGI Origin box as it is. so the solution can
    > not include "tweaking" the FORTRAN code in any way. i have to treat
    > the CFD program as an immutable black box.
    >

    You don't need to go to any trouble, any g or f format will work, as Fortran
    reads accept [DEe] as equivalent. As in C, the format of the input doesn't
    affect whether it is read as single (float) or double precision. The
    comments are probably optional.
    Tim Prince, Apr 11, 2004
    #5
  6. google

    Dan Pop Guest

    In <> (google) writes:

    >now on to the problem. the input file to the FORTRAN CFD program is
    >in the following format (which may look familiar to folks well versed
    >in FORTRAN, which i'm not):
    >(ronin)$ cat boundedmatrix.in
    >1.0D0 ! Ratio
    >1.5D0 ! AXMAX
    >1 ! NPNAX
    >1D-1 ! B
    >
    >the format of the FORTRAN input parameters, as you can see, carries
    >the precision of the value with it. e.g., 1.0D0 is a double precision
    >value X 10^0. and, 1D-1 is a double precision value X 10^-1.


    As Tim Prince mentioned, this is true in Fortran source code, where
    1.0D0 is a double precision constant, while 1.0E0 is a single precision
    constant. In READ statements, the precision is already known from the
    way the variable was declared, so both D and E are accepted.

    >now then, i'm a complete novice when it comes to FORTRAN, and denoting
    >the value precision in the input file in this way seems, to this C
    >programmer, to be a little odd. but nevertheless that's the way it
    >is.
    >
    >does anyone have any ideas on how i might get my fprintf()'s to output
    >these kinds of values without a lot of gymnastics?


    You only need a minimal amount of gymnastics, if you *really* want to
    use 'D' instead of 'E': use sprintf with the %E format, then use strchr
    to find the first 'E' character and replace it by 'D'. Output the
    string to the file with fputs.

    char line[LINESIZE], *p;
    double ratio;
    FILE *fp;
    ....
    sprintf(line, "%-20E! Ratio\n", ratio);
    if ((p = strchr(line, 'E')) != NULL) *p = 'D';
    fputs(line, fp);

    I used %-20E instead of a plain %E so that your comments get nicely
    aligned, as in your example above. You may also want to use a precision
    specification, if the values are computed in your program with more
    precision than the default six digits implied by the absence of a
    precision specification.

    In the pathological case when the value is a NaN, my if statement may
    replace an 'E' inside a comment by a 'D' ;-) If NaN's in the input
    file are a real option, you can avoid this by adding an extra check:

    if (ratio == ratio && (p = strchr(line, 'E')) != NULL) *p = 'D';

    NaNs don't compare equal, so a NaN-aware compiler cannot assume that
    ratio == ratio always evaluates to true. And this test is more portable
    than the isnan macro (which need not be supported by C89 implementations).

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Apr 13, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    431
    Barry Schwarz
    Jan 2, 2004
  2. Harry

    fprintf format specifiers

    Harry, Oct 12, 2006, in forum: C Programming
    Replies:
    9
    Views:
    464
    Christopher Benson-Manica
    Oct 13, 2006
  3. Gary Wessle

    fprintf format

    Gary Wessle, Aug 4, 2006, in forum: C++
    Replies:
    5
    Views:
    555
    Gary Wessle
    Aug 4, 2006
  4. Luna Moon
    Replies:
    9
    Views:
    608
    Guest
    Sep 4, 2007
  5. deadpickle
    Replies:
    1
    Views:
    984
    Jens Thoms Toerring
    Nov 7, 2010
Loading...

Share This Page