Task: Fix #3790: Collision rate for MTS BAOAB Langevin integrator now correctly accounts for number of substeps (openmm/openmm#3791)

org: openmm
repo: openmm
pr_number: 3791
issue_title: Fix #3790: Collision rate for MTS BAOAB Langevin integrator now correctly accounts for number of substeps
issue_body: Previously, `openmm.MTSLangevinIntegrator` would use an effective collision rate that is too large when there were multiple steps, since every substep used the outer timestep instead of the inner substep timestep to apply the friction.

This PR corrects this, using a fix suggested by Charlie Matthews (@c-matthews) in #3790.
resolved_issues: number: 3790
title: MTSLangevinIntegrator friction bug
body: Hi all, I think I found a bug in the [MTS Langevin Integrator](https://github.com/openmm/openmm/blob/be19e0222ddf66f612016a3c1f687161a53c2396/wrappers/python/openmm/mtsintegrator.py) code.

Currently the routine defines constants `a` and `b` as

https://github.com/openmm/openmm/blob/be19e0222ddf66f612016a3c1f687161a53c2396/wrappers/python/openmm/mtsintegrator.py#L170-L171

and then applies an Ornstein-Uhlenbeck update using these constants _at every substep_

https://github.com/openmm/openmm/blob/be19e0222ddf66f612016a3c1f687161a53c2396/wrappers/python/openmm/mtsintegrator.py#L187-L192

The problem being that if I have $N$ substeps then I effectively am using $N\times$ the friction in simulation, which can affect diffusion coefficients and the like.

An easy fix would be to redefine the `a` and `b` constants to divide the per-substep OU update by the number of total substeps, something like

    total_substeps = math.prod( [group_size for (group_id, group_size) in groups] )
    self.addGlobalVariable("a", math.exp(-friction*dt / total_substeps))
    self.addGlobalVariable("b", math.sqrt(1-math.exp(-2*friction*dt / total_substeps)))

That way the total damping should be correct. An alternative would be to give the user control of how the damping is allocated between the groups.

Cheers - CM

## IMPORTANT INSTRUCTIONS

1. If you edit a python file, you MUST run 'make PythonInstall' inside the build directory
2. If you edit a c++ file, you MUST run 'make -j4 && make install" inside the build directory

Reference solution:
fix_patch: diff --git a/wrappers/python/openmm/mtsintegrator.py b/wrappers/python/openmm/mtsintegrator.py
index dcae295562..5014e31a36 100644
--- a/wrappers/python/openmm/mtsintegrator.py
+++ b/wrappers/python/openmm/mtsintegrator.py
@@ -167,8 +167,9 @@ def __init__(self, temperature, friction, dt, groups):
         self.temperature = temperature
         self.friction = friction
         import math
-        self.addGlobalVariable("a", math.exp(-friction*dt))
-        self.addGlobalVariable("b", math.sqrt(1-math.exp(-2*friction*dt)))
+        total_substeps = groups[-1][1]
+        self.addGlobalVariable("a", math.exp(-friction*dt / total_substeps))
+        self.addGlobalVariable("b", math.sqrt(1-math.exp(-2*friction*dt / total_substeps)))
         from openmm.unit import MOLAR_GAS_CONSTANT_R
         self.addGlobalVariable('kT', MOLAR_GAS_CONSTANT_R*temperature)
         self.addPerDofVariable("x1", 0)