@@ -121,6 +121,75 @@ def extract_fragment(
121121 selection_string = f"index { frag .indices [0 ]} :{ frag .indices [- 1 ]} "
122122 return self .select_atoms (universe , selection_string )
123123
124+ def convert_lammps (
125+ self ,
126+ tprfile : str ,
127+ trrfile ,
128+ fileformat : str | None = None ,
129+ ) -> mda .Universe :
130+ """Update the units produced from the universe produced from LAMMPS
131+ format topology and trajectory files. MDA currently has a bug that
132+ results in forces not being converted to the correct units
133+ (see issue for more details:
134+ https://github.com/MDAnalysis/mdanalysis/issues/5115
135+ )
136+ The method currently expects the following additional columns in the
137+ lammps dump file: fx fy fz c_5 c_7
138+ where c_5 and c_7 are the atom potential and kinetic energies respectively.
139+
140+ This method loads:
141+
142+ - Coordinates and dimensions from the coordinate trajectory
143+ (``tprfile`` + ``trrfile``).
144+
145+ Args:
146+ tprfile: Topology input file.
147+ trrfile: Coordinate trajectory file(s). This can be a single path or a
148+ list, as accepted by MDAnalysis.
149+ fileformat: Optional file format for the coordinate trajectory, as
150+ recognised by MDAnalysis.
151+
152+ Returns:
153+ MDAnalysis.Universe: A new Universe containing coordinates, forces and
154+ dimensions loaded into memory.
155+
156+ Raises:
157+ ValueError: If fileformat is not one of the supported values.
158+ """
159+
160+ def _convert_lammps_forces_energies (ts ):
161+ """
162+ Convert lammps forces from kcal/mol/Ang to kJ/mol/Ang.
163+ Assumes columns for per-atom potential (c_5) and kinetic energies (c_7)
164+ are provided and converts these too.
165+
166+ Args:
167+ ts: MDAnalysis timeseries from the trajectory.
168+
169+ Returns:
170+ A converted time series.
171+ """
172+ ts .forces *= 4.184
173+ ts .data ["c_5" ] *= 4.184
174+ ts .data ["c_7" ] *= 4.184
175+ return ts
176+
177+ if fileformat == "LAMMPSDUMP" :
178+ try :
179+ return mda .Universe (
180+ tprfile ,
181+ trrfile ,
182+ format = fileformat ,
183+ additional_columns = ["fx" , "fy" , "fz" , "c_5" , "c_7" ],
184+ transformations = [_convert_lammps_forces_energies ],
185+ )
186+ except KeyError :
187+ raise
188+ else :
189+ raise ValueError (
190+ f"Incorrect file format: { fileformat } , LAMMPSDUMP expected"
191+ )
192+
124193 def merge_forces (
125194 self ,
126195 tprfile : str ,
0 commit comments