Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lambda-ABF implementation for the NAMD interface #649

Merged
merged 13 commits into from
Dec 19, 2024
Merged

Conversation

jhenin
Copy link
Member

@jhenin jhenin commented Jan 19, 2024

As fully documented in the Lagardère et al. paper
complements the Tinker-HP implementation, which is maintained on the Tinker-HP repo.

TODO

  • Regression tests
  • Document current limitations in ref. manual

Update: why are there no regression tests? Because of a synchronization issue in NAMD, where the current alchemical colvar interface is plugged into a "non-urgent" output routine, which causes it to run in a variable order with respect to the Colvars calculation. This causes variations in the instantaneous trajectory, even though it cancels out of the ensemble averages, so the free energies are correct. This causes failures in regression tests, which are by design sensitive to trajectory details. The GPU-resident code path of NAMD is immune from this problem and produces reproducible trajectories: it is therefore the recommended way to use this code in NAMD.

@fhh2626
Copy link
Contributor

fhh2626 commented Mar 17, 2024

Hi @jhenin , I just read your excellent λ-ABF paper and then found this PR. I can't wait to give it a try. Is there any guide about how to write the Colvars file?
Thanks,
Haohao

@jhenin
Copy link
Member Author

jhenin commented Mar 17, 2024

Hi Haohao,
The NAMD implementation still needs some refinement: it comes with performance limitations, namely, you cannot use MTS and you need energy computation every time step. Other than that, it works perfectly, and the performance is not so bad at all.

Here is an example input (using HMR):

timestep                2.0
fullElectFrequency      1
nonbondedFreq           1

# For NAMD3
computeEnergies 1

alch                    on
alchFile                        $alchconfig
alchCol                 B                    
alchOutFreq             1000

alchOutFile             $outName.fepout
alchElecLambdaStart     0.5                  
alchVdwLambdaEnd        1.0            
alchVdwShiftCoeff       5.0         
alchdecouple            on

alchType                TI
alchlambda 0

colvars                on 

cv config "
smp off  # Necessary for shared ABF
colvar {
  name l
  extendedLagrangian on
  extendedMass 150000
  extendedLangevinDamping 1000

   lowerBoundary 0
   upperBoundary 1
   reflectingLowerBoundary
   reflectingUpperBoundary
   width 0.01
  alchLambda {
  }
  outputTotalForce
  outputAppliedforce
}

 abf {
   colvars l
   fullSamples 1000
   outputFreq  50000
   historyFreq 100000
   shared on
   sharedFreq 5000
}
"

cv configfile $CVconfig
cv configfile common/protein_tilt.colvars

cv config "
colvarsTrajFrequency 100
colvarsRestartFrequency 100000"

@fhh2626
Copy link
Contributor

fhh2626 commented Mar 18, 2024

Hi Haohao, The NAMD implementation still needs some refinement: it comes with performance limitations, namely, you cannot use MTS and you need energy computation every time step. Other than that, it works perfectly, and the performance is not so bad at all.

Here is an example input (using HMR):

timestep                2.0
fullElectFrequency      1
nonbondedFreq           1

# For NAMD3
computeEnergies 1

alch                    on
alchFile                        $alchconfig
alchCol                 B                    
alchOutFreq             1000

alchOutFile             $outName.fepout
alchElecLambdaStart     0.5                  
alchVdwLambdaEnd        1.0            
alchVdwShiftCoeff       5.0         
alchdecouple            on

alchType                TI
alchlambda 0

colvars                on 

cv config "
smp off  # Necessary for shared ABF
colvar {
  name l
  extendedLagrangian on
  extendedMass 150000
  extendedLangevinDamping 1000

   lowerBoundary 0
   upperBoundary 1
   reflectingLowerBoundary
   reflectingUpperBoundary
   width 0.01
  alchLambda {
  }
  outputTotalForce
  outputAppliedforce
}

 abf {
   colvars l
   fullSamples 1000
   outputFreq  50000
   historyFreq 100000
   shared on
   sharedFreq 5000
}
"

cv configfile $CVconfig
cv configfile common/protein_tilt.colvars

cv config "
colvarsTrajFrequency 100
colvarsRestartFrequency 100000"

Thank you very much! Just one additional question. I need to use HMR to enable a timestep of 2fs?

@jhenin
Copy link
Member Author

jhenin commented Mar 18, 2024

In alchemical simulations, I usually scale down the timestep, because one of the end points has a molecule in gas phase. Depending on the nature of the ligand, you may get stable simulations at larger timesteps.

@fhh2626
Copy link
Contributor

fhh2626 commented Mar 18, 2024

Thanks for your clarification!

@jhenin jhenin force-pushed the lambdadyn_namd branch 3 times, most recently from bb446e4 to ad9d897 Compare April 16, 2024 15:55
@jhenin jhenin force-pushed the lambdadyn_namd branch 2 times, most recently from a325994 to b094ab9 Compare June 5, 2024 13:27
@fhh2626
Copy link
Contributor

fhh2626 commented Jun 7, 2024

Hi, @jhenin ,
I suggest also make available the Colvars harmonic restraints as the alchemical CVs, which will let us completely give up FEP/TI in binding free energy calculations.
Haohao

@jhenin jhenin force-pushed the lambdadyn_namd branch 3 times, most recently from 0674e73 to ec218d0 Compare June 10, 2024 12:15
@jhenin
Copy link
Member Author

jhenin commented Jun 10, 2024

Hi, @jhenin , I suggest also make available the Colvars harmonic restraints as the alchemical CVs, which will let us completely give up FEP/TI in binding free energy calculations. Haohao

Thanks Haohao, I like the idea.

@jhenin jhenin force-pushed the lambdadyn_namd branch 2 times, most recently from f580527 to d76c074 Compare September 1, 2024 08:18
@jhenin jhenin force-pushed the lambdadyn_namd branch 2 times, most recently from 0e6d067 to 255a566 Compare September 22, 2024 17:20
@jhenin jhenin marked this pull request as ready for review October 21, 2024 13:09
Save pointer to NAMD Controller in proxy

this is necessary for accessing the Controller from threads other than 0

Simplify accelMD call

Use alch lambda value from state file

Dependencies updates and fixes

- distinguish f_cv_gradient and f_cv_apply_force
- rename external cvs "driven"
- fix bug where error messages were not informative for complex
dependency resolution failures

Lambda-dynamics improvements

- add total_force_current_step feature
- follow lambda value from back-end

Remove unused variables

Enable scriptedColvarforces in ABMD script

Allow scripted forces on external param

Print unscaled biasing force in MTS
Select correct force bin on a per-colvar basis
So far is was erroneously set to true, but its effects were not fully
implemented in ABF.
removes spurious error messages
Had to force single-thread calculation to work around unreliable results on the singel timestep level
Copy link
Member

@giacomofiorin giacomofiorin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall save for some minor comments.

Comment on lines +300 to 305
/// \brief A variable that constrains or follows an external parameter
/// in the back-end (eg. an alchemical coupling parameter for lambda-dynamics)
/// If extended Lagrangian, then we drive the external parameter
/// Otherwise we follow it
/// Can have a single component
f_cv_external,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be okay with this in a pinch, but ideally I'd like to distinguish it from other "external" objects that are computed in a reproducible way (centers of mass, volumetric maps). Are you using this just to circumvent the check below?

        cvm::error("Error: the calculated value of colvar \""+name+
                   "\":\n"+cvm::to_str(x)+"\n differs greatly from the value "
                   "last read from the state file:\n"+cvm::to_str(x_restart)+
                   "\nPossible causes are changes in configuration, "
                   "wrong state file, or how PBC wrapping is handled.\n",
                   COLVARS_INPUT_ERROR);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used in many places in colvar.cpp. Another way to describe this feature is: this colvar is not a function of atom coordinates, it contains a special CVC that is communicated to and from the back-end through a separate mechanism. I'm happy to rename it if you have a better name, but I don't see an alternative to this feature.

src/colvardeps.h Show resolved Hide resolved
src/colvarbias.cpp Outdated Show resolved Hide resolved
src/colvarcomp.cpp Show resolved Hide resolved
src/colvardeps.cpp Show resolved Hide resolved
namd/src/colvarproxy_namd.h Show resolved Hide resolved
src/colvar.cpp Outdated

// when total atomic forces are obtained from the previous time step,
// we cannot (currently) have colvar values and projected total forces for the same timestep
// TODO this will need refining for driven alchemical parameters
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by "driven alchemical parameters"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Driven" means Colvars is responsible for integrating (driving) the dynamics of this parameter. For the current version of this, see

if (!is_enabled(f_cv_total_force_current_step)) {

src/colvar.cpp Outdated Show resolved Hide resolved
- move step zero data test from colvarbias.cpp to ABF
- properly test for driven external parameter
@jhenin jhenin merged commit 30d66a3 into master Dec 19, 2024
15 checks passed
@jhenin jhenin deleted the lambdadyn_namd branch December 19, 2024 19:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants