One hack is to write a quick C++ routine that you can bind to a C name.
This function reassigns the value of lmp->screen to another file (with
a name) that you open in that function. This must be called AFTER you
initialize LAMMPS. Such a routine might look something like,
#include "lammps.h"
#include <cstdio>
void reset_screen (void *ptr)
{
FILE *newscreen = fopen("my_output_file.txt", "w");
LAMMPS *lmp = static_cast<LAMMPS*> (ptr);
lmp->screen = newscreen;
}
For a non-hard-coded way, read on....
There actually IS no 100% portable way to pass a string from FORTRAN 77
to C (that's why the ISO_C_BINDING module was written for Fortran 2003).
However, most Fortran 90 compilers will "get it right" if you use
technically non-portable methods that assume the following:
* C strings are terminated by ASCII code zero (CHAR(0) should work
in FORTRAN 77, and either that or ACHAR(0) will work on newer
compilers that support Fortran 90). ISO_C_BINDING stores this as the
constant C_NULL_CHAR, which is guaranteed portable
* Fortran strings are "scalar" quantities with an associated length, and
are distinct from character arrays
* C strings and Fortran character arrays are generally stored the same
way, but C strings are not stored the same way as Fortran strings
(i.e., characters with len /= 1). This is guaranteed true if the
compiler supports ISO_C_BINDING and you have declared the character's
KIND to be C_CHAR
* Spaces at the end of Fortran strings are not significant
I am nearly certain that the following function will convert a Fortran
string to a C string portably,
pure function string2Cstring (string) result (C_string)
use, intrinsic :: ISO_C_binding, only : C_char, C_NULL_CHAR
character (len=*), intent(in) :: string
character (len=1, kind=C_char) :: C_string (len_trim(string)+1)
integer :: i, n
n = len_trim (string)
forall (i = 1:n)
C_string(i) = string(i:i)
end forall
C_string(n+1) = C_NULL_CHAR
end function string2Cstring
assuming you can use ISO_C_binding. If not, try omitting that line and
anything that breaks (e.g., kind=C_char). The FORALL loop might also need
to be changed to a plain DO loop.
This gets you half way there. The second half is to convert that
C-style string to a tokenized list of command arguments, which is tricky
because you have to make certain the Fortran compiler doesn't deallocate
things that the C compiler still expected to be allocated. My version of
that routine is too long to post on the list, though. Instead, you could
write the following C routine that initializes LAMMPS based on a single
command line (which you generate in Fortran, perhaps):
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "library.h"
void init_lammps (void **lmp, const char *command_line) {
char **new_argv = NULL, *tok = NULL, command[strlen(command_line+1];
int new_argc = 0, nargs = 0;
strcpy (command, command_line);
tok = strtok (command, " \t\n\r");
while (tok != NULL) { nargs += 1; tok = strtok (NULL, " \t\n\r"); }
new_argv = (char**) malloc (nargs*sizeof(char*));
strcpy (command, command_line);
tok = strtok (command, " \t\n\r");
while (tok != NULL) {
new_argv[new_argc++] = tok;
tok = strtok (NULL, " \t\n\r");
}
lammps_open_no_mpi (new_argc, new_argv, lmp);
free (new_argv);
}
That should essentially do what the shell does, converting your string to
an argc/argv pair. It might be confused by quoted strings, though.
Karl D. Hammond
University of Tennessee, Knoxville
[email protected]...
"You can never know everything, and part of what you know is always
wrong. A portion of wisdom lies in knowing that. A portion of courage
lies in going on anyway."
"Nothing ever goes as you expect. Expect nothing, and you will not be
surprised."
Message: 8
Date: Sun, 12 Aug 2012 06:42:50 +0200
From: Axel Kohlmeyer <[email protected]>
Subject: Re: [lammps-users] Restrict screen output calling from
Fortran
To: "Gardner, David James" <[email protected]...>
Cc: "[email protected]"
<[email protected]>
Message-ID:
<[email protected]...>
Content-Type: text/plain; charset=ISO-8859-1
david,
Hello all,
I'm trying to couple LAMMPS to a Fortran code and would like to have
LAMMPS write screen information to a file or not print any information
to the screen.I see when using LAMMPS at the command line this can be done with
-screen file and -screen none but I do not see how to do this when
calling LAMMPS as a library.it can be easily done, in principle when you call lammps from C or C++,
but from fortran it i not as easy, since there is no *easy and portable*
way to pass an argument array from fortran to C.you have essentially three choices:
use the fortran 2003/2008 style iso C
bindings and the C library interface,or make a suggestion what would be
a good and portable way to pass the
list of arguments from fortran to C
(in a fortran 77 compatible way by preference)or hack the fortran library wrapper to
provide the flags that you want to be
when initializing the lammps object.let us know, if you have additional
questions on this.ciao,
axel.Thanks,
David
----------------------------------------------------------------------------$
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond.
Discussions
will include endpoint security, mobile security and the latest in
malware