I am currently working on a project that requires access to the KSpace forces without directly adding them to the total force array. This is essential for testing purposes and for implementing custom fix classes. Currently, users can set compute keywords to choose whether to perform kspace compute or not. But it does not work if we want to access the kspace forces on-the-fly.
To facilitate my project, I would like to propose the following modifications to the KSpace class:
Add a public 2D array (e.g., float **fkspace) to store the KSpace force contributions explicitly.
Introduce a new keyword argument, sfactor, which scales the cumulative KSpace forces. The default value will be set to 1.0 to preserve the current behavior.
With these additions, it will be possible to implement custom compute or fix classes that can access kspace->fkspace directly, offering more flexibility for advanced force manipulation and analysis.
I would greatly appreciate your thoughts on this proposal, and whether such changes align with the development goals of LAMMPS.
Thank you for your time.
But…
There is nothing stopping you from implementing a custom KSpace class that stores the created forces before adding them to the total forces. Those can be made available to other classes via the extract() function.
A scale factor like you describe already exists and is used, for example. by fix adapt.
If I understand correctly, @ChiahsinChu is proposing to add an option to the KSpace class to control its behavior. When this option is turned on, the KSpace class would store the computed force contributions in a member variable, fkspace, instead of applying them directly to the total force array. This would allow other commands to access the data afterward.
In my opinion, compared to requiring users to create a custom KSpace class, adding a configurable option to the existing KSpace class might be a better approach. The reasons are as follows:
It is controlled by a switch, and users must opt in to enable it. Therefore, it does not affect existing users and introduces no additional overhead.
This feature may benefit other developers who wish to perform custom processing based on the output of the KSpace module. It avoids the need to create a custom KSpace class, which can be difficult to maintain and integrate into LAMMPS, and may complicate code sharing and compilation.
I would like to update the plan, according to what Axel suggested. Now we only need to store the (unscaled) kspace output somewhere we can access later from other classes. Using fix adapt/fep can modify the scaling factor for kspace output added to the total properties.
@link89 Please note that the main concern is the maintainability and consistent behavior of LAMMPS itself. We’re not storing subsets of generated forces anywhere at the moment. There is no mechanism to turn that kind of feature on or off and so on.
If that means some complication for an individual project, that is something that can happen.
Creating a custom class is not a significant effort, if one proposes changes that are rather low level in the first place.
Since LAMMPS is open source, there is no restriction to make the proposed change in a personal branch and share that version if the alternative is too much effort. There are plenty of folks that do just this (and then there some that should do it).
But it is also the choice of the LAMMPS developers whether they want those kinds of changes in their tree.
Come to think of it. You should check out run style verlet/split. This runs kspace on a separate partition, so it may be possible to access only the kspace forces on that partition.
Of course, that will require extra communication, since it is a multi-partition run.
That is not true. You would have to work rather hard to reduce overhead, for example caused by putting if statements into the inner loop. And you would have to make changes to all kspace styles or add another complication that there is a flag that indicates whether a specific kspace style is compatible with maintaining an extra copy of the forces.
… and as mentioned before, this kind of change would only be acceptable if it was made consistently throughout LAMMPS. That would require changing about 400 different styles, plus their accelerated (GPU, INTEL, KOKKOS, OPENMP, OPT) versions where available.
As far as I can tell, the kspace->compute(eflag, vflag) function is public, which lets it be called by any other class.
So you could reasonably write a fix that:
Checks that KSpace is set to “compute no” (and errors otherwise)
Has a pre_reverse function that
Stores a copy of the existing forces
and then calls kspace->compute
Which can then compare the stored and new forces to infer the KSpace forces (which can be accessed by other fixes as a per-atom array) and do any desired scaling.
This fix would not modify any core LAMMPS functionality and be automatically future-proof against any new KSpace implementations (as long as the kspace.h class itself remains unchanged).