Apply external forces on atoms given Lammps coupled with fortran driver

Dear Lammps users,

I appreciate if anyone can give some insight on what will be an efficient way to transfer a calculated fortran vector as external force back into lammps, giving that lammps is compiled as library and driven by the fortran program

As I have seen previous discussions showing that
fix external pf/callback
being a good way to use it, yet if I wanted to do this under a fortran 03 platform, I found it is not that simple to get access into lammps data structure.

Thanks!

All of the methods in the library interface (library.cpp and library.h)
have a C-style interface. You can write additional ones yourself. That
means they are all callable from Fortran. See the gather_atoms
and scatter_atoms as examples, or extract_atom() to get a raw pointer
to the C force array, which Fortran could work with.

Fix external works the opposite direction. It makes a callback to
the driving program (e.g. your Fortran code). That is also a C-style
call. So for Fortran you should be able to write a small C method
that is called by LAMMPS and use it to put the data from LAMMPS
into suitable Fortran data structs visible to the Fortran (e.g. a common
block) or make a call to a Fortran method and pass those values
in a manner that Fortran needs it (e.g. by reference).

Steve

Dear Lammps users,

I appreciate if anyone can give some insight on what will be an efficient
way to transfer a calculated fortran vector as external force back into
lammps, giving that lammps is compiled as library and driven by the fortran
program

​you need to provide some more details of what your vector encompasses and
where and what information you want to feed back to LAMMPS. you also need
to keep in mind, that LAMMPS usually is running in parallel and then each
MPI rank has only access to a subset of the atoms to add those forces to.​

As I have seen previous discussions showing that

fix external pf/callback
being a good way to use it, yet if I wanted to do this under a fortran 03
platform, I found it is not that simple to get access into lammps data
structure.

​welcome to the world of "life would be so much easier, if i had done this
in C/C++".

before you venture into going this route, you should let us know what your
level of programming experience is and how familiar you are with the
concept of callbacks. particularly in the world of fortran programming,
this is usually not a given.​ you *can* make fortran 03 look like C using
the ISO_C_BINDING​S module and related tools and flags, but that still
requires a good understanding of what is happening behind the scenes when
using these features. thus it may be easier to check out the fortran 03
style interface in examples/COUPLE/fortran2. unfortunately, a lot of those
"modern" fortran features lead to rather convoluted and hard to understand
code, which makes it difficult to figure something out. thus my final
recommendation is to consider rewriting your code in C/C++ and just writing
a simple fix (provided the code is simple enough to do this).

axel.

Thanks for the suggestions, what I am doing is couple the lammps with a in-house fortran finite element code to iteratively solve the equilibrium the coupled system.
Every iteration step I calculate the external force on atoms, the task I am facing is put this fortran vector back into lammps like what lammps_scatter_atoms does.
This is extra force so directly working on atom->f seems not right.

I am thinking maybe using " variable all atom " and " fix addforce" will work if I can scatter the fortran vector into the variable that I defined. Do you think this will be a more efficient way?

Thanks for the suggestions, what I am doing is couple the lammps with a
in-house fortran finite element code to iteratively solve the equilibrium
the coupled system.
Every iteration step I calculate the external force on atoms, the task I
am facing is put this fortran vector back into lammps like what
lammps_scatter_atoms does.
This is extra force so directly working on atom->f seems not right.

I am thinking maybe using " variable all atom " and " fix addforce" will
work if I can scatter the fortran vector into the variable that I defined.
Do you think this will be a more efficient way?

​i don't know. there is still too little information about what your
in-house code does and how. in any case, what i would do in your situation
is to set up a *very* simple test system and then write a dummy code that
just adds some fixed amount of force to atoms and then implement this via
either the library interface or ​fix external and then compare it to doing
the same thing with fix addforce. test this in serial and parallel and if
both matches, then you can continue and expand the dummy code into a full
interface to your fortran code.

axel.

This is exactly what fix external is designed to do. If you look at the code
in FixExternal::post_force() you will see it passes a force vector (fexternal)
to an external function (in your Fortran code). The external code fills
the vector, and LAMMPS adds it to the existing forces per atom.

As I said in the earlier email, your Fortran code can be linked with a simple
C function (that you write), that is what fix external calls. You can write
that function to then make a call into your Fortran code and pass whatever
information you want that Fortran needs, e.g. convert values into pointers
so they are compatible with Fortran call-by-reference.

Steve