@@ -781,6 +781,9 @@ def generate_lam_vals(lambda_base, increment=0.001):
781781 save_frames = self ._config .frame_frequency > 0
782782 next_frame = self ._config .frame_frequency
783783 flip_counter = 0
784+ # Track elapsed simulation time separately for energy components,
785+ # since dynamics blocks increment by gcmc_frequency not energy_frequency.
786+ ec_elapsed = _sr .u ("0ps" )
784787
785788 # Loop until we reach the runtime.
786789 while runtime < checkpoint_frequency :
@@ -863,6 +866,56 @@ def generate_lam_vals(lambda_base, increment=0.001):
863866
864867 # Update the runtime and flip counter.
865868 runtime += self ._config .energy_frequency
869+ ec_elapsed += self ._config .gcmc_frequency
870+ flip_counter += 1
871+
872+ # Save the energy contribution for each force.
873+ if self ._config .save_energy_components :
874+ self ._save_energy_components (
875+ index ,
876+ dynamics .context (),
877+ (block * checkpoint_frequency + ec_elapsed ).to (
878+ "ns"
879+ ),
880+ )
881+
882+ elif self ._config .save_energy_components :
883+ # Sub-block loop to save energy components at energy_frequency
884+ # intervals, with optional terminal flip moves.
885+ runtime = _sr .u ("0ps" )
886+ flip_counter = 0
887+ while runtime < checkpoint_frequency :
888+ if (
889+ terminal_flip_sampler is not None
890+ and flip_counter % flip_every == 0
891+ ):
892+ _logger .info (
893+ f"Performing terminal flip move at "
894+ f"{ _lam_sym } = { lambda_value :.5f} "
895+ )
896+ if (
897+ terminal_flip_sampler .move (dynamics .context ())
898+ and self ._config .randomise_velocities
899+ ):
900+ dynamics .randomise_velocities ()
901+ dynamics .run (
902+ self ._config .energy_frequency ,
903+ energy_frequency = self ._config .energy_frequency ,
904+ frame_frequency = self ._config .frame_frequency ,
905+ lambda_windows = lambda_array ,
906+ rest2_scale_factors = rest2_scale_factors ,
907+ save_velocities = self ._config .save_velocities ,
908+ auto_fix_minimise = self ._config .auto_fix_minimise ,
909+ num_energy_neighbours = num_energy_neighbours ,
910+ null_energy = self ._config .null_energy ,
911+ save_crash_report = self ._config .save_crash_report ,
912+ )
913+ runtime += self ._config .energy_frequency
914+ self ._save_energy_components (
915+ index ,
916+ dynamics .context (),
917+ (block * checkpoint_frequency + runtime ).to ("ns" ),
918+ )
866919 flip_counter += 1
867920
868921 elif terminal_flip_sampler is not None :
@@ -924,12 +977,6 @@ def generate_lam_vals(lambda_base, increment=0.001):
924977 # Commit the current system.
925978 system = dynamics .commit ()
926979
927- # Save the energy contribution for each force.
928- if self ._config .save_energy_components :
929- self ._save_energy_components (
930- index , dynamics .context (), system .time ().to ("ns" )
931- )
932-
933980 # If performing GCMC, then we need to flag the ghost waters.
934981 if gcmc_sampler is not None :
935982 system = gcmc_sampler ._flag_ghost_waters (system )
@@ -1103,7 +1150,7 @@ def generate_lam_vals(lambda_base, increment=0.001):
11031150 )
11041151 except Exception as e :
11051152 raise RuntimeError (
1106- f"Final dynamics block for { lam_sym } = { lambda_value :.5f} failed: { e } "
1153+ f"Final dynamics block for { _lam_sym } = { lambda_value :.5f} failed: { e } "
11071154 )
11081155 else :
11091156 try :
@@ -1113,6 +1160,9 @@ def generate_lam_vals(lambda_base, increment=0.001):
11131160 save_frames = self ._config .frame_frequency > 0
11141161 next_frame = self ._config .frame_frequency
11151162 flip_counter = 0
1163+ # Track elapsed simulation time separately for energy components,
1164+ # since dynamics blocks increment by gcmc_frequency not energy_frequency.
1165+ ec_elapsed = _sr .u ("0ps" )
11161166
11171167 # Loop until we reach the runtime.
11181168 while runtime < time :
@@ -1182,6 +1232,56 @@ def generate_lam_vals(lambda_base, increment=0.001):
11821232
11831233 # Update the runtime and flip counter.
11841234 runtime += self ._config .energy_frequency
1235+ ec_elapsed += self ._config .gcmc_frequency
1236+ flip_counter += 1
1237+
1238+ # Save the energy contribution for each force.
1239+ if self ._config .save_energy_components :
1240+ self ._save_energy_components (
1241+ index ,
1242+ dynamics .context (),
1243+ (self ._config .runtime - time + ec_elapsed ).to ("ns" ),
1244+ )
1245+
1246+ elif self ._config .save_energy_components :
1247+ # Sub-block loop to save energy components at energy_frequency
1248+ # intervals, with optional terminal flip moves.
1249+ runtime = _sr .u ("0ps" )
1250+ flip_counter = 0
1251+ # Elapsed time before this run (0 for fresh, restart time for restart).
1252+ time_base = self ._config .runtime - time
1253+ while runtime < time :
1254+ if (
1255+ terminal_flip_sampler is not None
1256+ and flip_counter % flip_every == 0
1257+ ):
1258+ _logger .info (
1259+ f"Performing terminal flip move at "
1260+ f"{ _lam_sym } = { lambda_value :.5f} "
1261+ )
1262+ if (
1263+ terminal_flip_sampler .move (dynamics .context ())
1264+ and self ._config .randomise_velocities
1265+ ):
1266+ dynamics .randomise_velocities ()
1267+ dynamics .run (
1268+ self ._config .energy_frequency ,
1269+ energy_frequency = self ._config .energy_frequency ,
1270+ frame_frequency = self ._config .frame_frequency ,
1271+ lambda_windows = lambda_array ,
1272+ rest2_scale_factors = rest2_scale_factors ,
1273+ save_velocities = self ._config .save_velocities ,
1274+ auto_fix_minimise = self ._config .auto_fix_minimise ,
1275+ num_energy_neighbours = num_energy_neighbours ,
1276+ null_energy = self ._config .null_energy ,
1277+ save_crash_report = self ._config .save_crash_report ,
1278+ )
1279+ runtime += self ._config .energy_frequency
1280+ self ._save_energy_components (
1281+ index ,
1282+ dynamics .context (),
1283+ (time_base + runtime ).to ("ns" ),
1284+ )
11851285 flip_counter += 1
11861286
11871287 elif terminal_flip_sampler is not None :
0 commit comments