diff --git a/doc/src/Commands_fix.txt b/doc/src/Commands_fix.txt
index e002c117701110fc6dd33e83865386f52d2bae3e..2b6f4a3080f586c1d713a71db61db15b53536fee 100644
--- a/doc/src/Commands_fix.txt
+++ b/doc/src/Commands_fix.txt
@@ -65,6 +65,7 @@ OPT.
 "eos/table/rx (k)"_fix_eos_table_rx.html,
 "evaporate"_fix_evaporate.html,
 "external"_fix_external.html,
+"ffl"_fix_ffl.html,
 "filter/corotate"_fix_filter_corotate.html,
 "flow/gauss"_fix_flow_gauss.html,
 "freeze"_fix_freeze.html,
diff --git a/doc/src/fix_ffl.txt b/doc/src/fix_ffl.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ea33dc432f749dbb636ef245323e1390644c0d5f
--- /dev/null
+++ b/doc/src/fix_ffl.txt
@@ -0,0 +1,124 @@
+<script type="text/javascript"
+  src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
+</script>
+<script type="text/x-mathjax-config">
+  MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "AMS"} } });
+</script>
+
+"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
+
+:link(lws,http://lammps.sandia.gov)
+:link(ld,Manual.html)
+:link(lc,Commands_all.html)
+
+:line
+
+fix ffl command :h3
+
+[Syntax:]
+
+fix ID id-group ffl tau Tstart Tstop seed \[flip-type\]  :pre
+
+ID, group-ID are documented in "fix"_fix.html command :ulb,l
+ffl = style name of this fix command :l
+tau = thermostat parameter (positive real) :l
+Tstart, Tstop = temperature ramp during the run :l
+seed = random number seed to use for generating noise (positive integer) :l
+one more value may be appended :l
+    flip-type  = determines the flipping type, can be chosen between rescale - no_flip - hard - soft, if no flip type is given, rescale will be chosen by default :pre
+:ule
+
+[Examples:]
+
+fix 3 boundary ffl 10 300 300 31415
+fix 1 all ffl 100 500 500 9265 soft :pre
+
+[Description:]
+
+Apply a Fast-Forward Langevin Equation (FFL) thermostat as described
+in "(Hijazi)"_#Hijazi. Contrary to
+"fix langevin"_fix_langevin.html, this fix performs both
+thermostatting and evolution of the Hamiltonian equations of motion, so it
+should not be used together with "fix nve"_fix_nve.html -- at least not
+on the same atom groups.
+
+The time-evolution of a single particle undergoing Langevin dynamics is described
+by the equations
+
+\begin\{equation\} \frac \{dq\}\{dt\} = \frac\{p\}\{m\}, \end\{equation\}
+
+\begin\{equation\} \frac \{dp\}\{dt\} = -\gamma p + W + F, \end\{equation\}
+
+where \(F\) is the physical force, \(\gamma\) is the friction coefficient, and \(W\) is a
+Gaussian random force.
+
+The friction coefficient is the inverse of the thermostat parameter : \(\gamma = 1/\tau\), with \(\tau\) the thermostat parameter {tau}.
+The thermostat parameter is given in the time units, \(\gamma\) is in inverse time units.
+
+Equilibrium sampling a temperature T is obtained by specifying the
+target value as the {Tstart} and {Tstop} arguments, so that the internal
+constants depending on the temperature are computed automatically.
+
+The random number {seed} must be a positive integer.  A Marsaglia random
+number generator is used.  Each processor uses the input seed to
+generate its own unique seed and its own stream of random numbers.
+Thus the dynamics of the system will not be identical on two runs on
+different numbers of processors.
+
+The flipping type {flip-type} can be chosen between 4 types described in
+"(Hijazi)"_#Hijazi. The flipping operation occurs during the thermostatting
+step and it flips the momenta of the atoms. If no_flip is chosen, no flip
+will be executed and the integration will be the same as a standard
+Langevin thermostat "(Bussi)"_#Bussi3. The other flipping types are : rescale - hard - soft.
+
+[Restart, fix_modify, output, run start/stop, minimize info:]
+
+The instantaneous values of the extended variables are written to
+"binary restart files"_restart.html.  Because the state of the random
+number generator is not saved in restart files, this means you cannot
+do "exact" restarts with this fix, where the simulation continues on
+the same as if no restart had taken place. However, in a statistical
+sense, a restarted simulation should produce the same behavior.
+Note however that you should use a different seed each time you
+restart, otherwise the same sequence of random numbers will be used
+each time, which might lead to stochastic synchronization and
+subtle artefacts in the sampling.
+
+This fix can ramp its target temperature over multiple runs, using the
+{start} and {stop} keywords of the "run"_run.html command.  See the
+"run"_run.html command for details of how to do this.
+
+The "fix_modify"_fix_modify.html {energy} option is supported by this
+fix to add the energy change induced by Langevin thermostatting to the
+system's potential energy as part of "thermodynamic
+output"_thermo_style.html.
+
+This fix computes a global scalar which can be accessed by various
+"output commands"_Howto_output.html.  The scalar is the cumulative
+energy change due to this fix.  The scalar value calculated by this
+fix is "extensive".
+
+[Restrictions:]
+
+In order to perform constant-pressure simulations please use
+"fix press/berendsen"_fix_press_berendsen.html, rather than
+"fix npt"_fix_nh.html, to avoid duplicate integration of the
+equations of motion.
+
+This fix is part of the USER-MISC package.  It is only enabled if
+LAMMPS was built with that package.  See the "Build
+package"_Build_package.html doc page for more info.
+
+[Related commands:]
+
+"fix nvt"_fix_nh.html, "fix temp/rescale"_fix_temp_rescale.html, "fix
+viscous"_fix_viscous.html, "fix nvt"_fix_nh.html, "pair_style
+dpd/tstat"_pair_dpd.html, "fix gld"_fix_gld.html, "fix gle"_fix_gle.html
+
+:line
+
+:link(Hijazi)
+[(Hijazi)] M. Hijazi, D. M. Wilkins, M. Ceriotti, J. Chem. Phys. 148, 184109 (2018)
+:link(Bussi3)
+[(Bussi)] G. Bussi, M. Parrinello, Phs. Rev. E 75, 056707 (2007)
+
diff --git a/doc/src/fixes.txt b/doc/src/fixes.txt
index f2f257b1346240f56256dbd4107198f437d30e27..9ab299465b9b0b129ffca7b886a166e27d16b984 100644
--- a/doc/src/fixes.txt
+++ b/doc/src/fixes.txt
@@ -46,6 +46,7 @@ Fixes :h1
    fix_eos_table_rx
    fix_evaporate
    fix_external
+   fix_ffl
    fix_filter_corotate
    fix_flow_gauss
    fix_freeze
diff --git a/doc/src/lammps.book b/doc/src/lammps.book
index bc5df982b70c02a666c30867623ae774d9af5c01..2efa690e18cd5a20c55d841d0aa65890b87dc589 100644
--- a/doc/src/lammps.book
+++ b/doc/src/lammps.book
@@ -266,6 +266,7 @@ fix_eos_table.html
 fix_eos_table_rx.html
 fix_evaporate.html
 fix_external.html
+fix_ffl.html
 fix_filter_corotate.html
 fix_flow_gauss.html
 fix_freeze.html
diff --git a/src/.gitignore b/src/.gitignore
index 02cb90fd414963d1ced4b23e2b4ad0f6b5d07694..e3c273ebefcbebc6d23495c3fdff0616008b7e00 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -429,6 +429,8 @@
 /fix_eos_table.h
 /fix_evaporate.cpp
 /fix_evaporate.h
+/fix_ffl.cpp
+/fix_ffl.h
 /fix_filter_corotate.cpp
 /fix_filter_corotate.h
 /fix_viscosity.cpp
diff --git a/src/USER-MISC/README b/src/USER-MISC/README
index eb221c07db67bbd8569ac7d61f4594af29b76654..b3c3e859480b0ba3e6bfbb1a501d684f02d284b3 100644
--- a/src/USER-MISC/README
+++ b/src/USER-MISC/README
@@ -44,6 +44,7 @@ dihedral_style table/cut, Mike Salerno, ksalerno@pha.jhu.edu, 11 May 18
 fix addtorque, Laurent Joly (U Lyon), ljoly.ulyon at gmail.com, 8 Aug 11
 fix ave/correlate/long, Jorge Ramirez (UPM Madrid), jorge.ramirez at upm.es, 21 Oct 2015
 fix bond/react, Jacob Gissinger (CU Boulder), info at disarmmd.org, 24 Feb 2018
+fix ffl, David Wilkins (EPFL Lausanne), david.wilkins @ epfl.ch, 28 Sep 2018
 fix filter/corotate, Lukas Fath (KIT), lukas.fath at kit.edu, 15 Mar 2017
 fix flow/gauss, Joel Eaves (CU Boulder), Joel.Eaves@Colorado.edu, 23 Aug 2016
 fix gle, Michele Ceriotti (EPFL Lausanne), michele.ceriotti at gmail.com, 24 Nov 2014
diff --git a/src/USER-MISC/fix_ffl.cpp b/src/USER-MISC/fix_ffl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e2fb0166a28473be73e33ddba4e5c746b2d6679d
--- /dev/null
+++ b/src/USER-MISC/fix_ffl.cpp
@@ -0,0 +1,483 @@
+/* ----------------------------------------------------------------------
+   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+   http://lammps.sandia.gov, Sandia National Laboratories
+   Steve Plimpton, sjplimp@sandia.gov
+
+   Copyright (2003) Sandia Corporation.  Under the terms of Contract
+   DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+   certain rights in this software.  This software is distributed under
+   the GNU General Public License.
+
+   See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+   Fast-forward Langevin thermostat, see
+   M. Hijazi, D. M. Wilkins, M. Ceriotti, J. Chem. Phys. 148, 184109 (2018)
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+   Contributing authors: Lionel Constantin (EPFL), David M. Wilkins (EPFL),
+			 Michele Ceriotti (EPFL)
+------------------------------------------------------------------------- */
+
+#include <mpi.h>
+#include <cmath>
+#include <cstring>
+#include <cstdlib>
+#include "fix_ffl.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "atom_vec_ellipsoid.h"
+#include "force.h"
+#include "update.h"
+#include "modify.h"
+#include "compute.h"
+#include "domain.h"
+#include "region.h"
+#include "respa.h"
+#include "comm.h"
+#include "input.h"
+#include "variable.h"
+#include "random_mars.h"
+#include "memory.h"
+#include "error.h"
+#include "group.h"
+
+using namespace LAMMPS_NS;
+using namespace FixConst;
+
+enum {NOBIAS,BIAS};
+enum {CONSTANT,EQUAL,ATOM};
+enum {NO_FLIP, FLIP_RESCALE, FLIP_HARD, FLIP_SOFT};
+//#define FFL_DEBUG 1
+
+#define MAXLINE 1024
+
+/* syntax for fix_ffl:
+ * fix nfix id-group ffl tau Tstart Tstop seed [flip_type]
+ *
+ *                                                                        */
+
+/* ---------------------------------------------------------------------- */
+
+
+FixFFL::FixFFL(LAMMPS *lmp, int narg, char **arg) :
+  Fix(lmp, narg, arg) {
+
+
+  if (narg < 7)
+    error->all(FLERR,"Illegal fix ffl command. Expecting: fix <fix-ID>"
+               " <group-ID> ffl <tau> <Tstart> <Tstop> <seed>  ");
+
+  restart_peratom = 1;
+  time_integrate = 1;
+  scalar_flag = 1;
+
+  //gamma = 1/ time constant(tau)
+  if (force->numeric(FLERR,arg[3]) <= 0)
+    error->all(FLERR,"Illegal fix ffl tau value, should be greater than 0");
+  gamma = 1.0/force->numeric(FLERR,arg[3]);
+  ffl_every=1;
+  ffl_step=0;
+
+  // start temperature (t ramp)
+  t_start = force->numeric(FLERR,arg[4]);
+
+  // final temperature (t ramp)
+  t_stop = force->numeric(FLERR,arg[5]);
+
+  // PRNG seed
+  int seed = force->inumeric(FLERR,arg[6]);
+
+  // Flip type used, uses rescale if no flip is given
+  if (narg == 8) {
+    if (strcmp(arg[7],"no_flip") == 0) {
+      flip_int = NO_FLIP;
+    } else if (strcmp(arg[7],"rescale") == 0) {
+      flip_int = FLIP_RESCALE;
+    } else if (strcmp(arg[7],"hard") == 0) {
+      flip_int = FLIP_HARD;
+    } else if (strcmp(arg[7],"soft") == 0) {
+      flip_int = FLIP_SOFT;
+    } else {
+      error->all(FLERR,"Illegal fix ffl flip type, only accepts : rescale - hard - soft - no_flip");
+    }
+  } else {
+    flip_int = FLIP_RESCALE;
+  }
+
+  t_target=t_start;
+  const double kT = t_target * force->boltz / force->mvv2e;
+
+
+  // initialize Marsaglia RNG with processor-unique seed
+  // NB: this means runs will not be the same with different numbers of processors
+  if (seed <= 0) error->all(FLERR,"Illegal fix ffl command");
+  random = new RanMars(lmp,seed + comm->me);
+
+  // allocate per-type arrays for mass-scaling
+  sqrt_m=NULL;
+  memory->grow(sqrt_m, atom->ntypes+1,"ffl:sqrt_m");
+
+  // allocates space for temporaries
+  ffl_tmp1=ffl_tmp2=NULL;
+
+  grow_arrays(atom->nmax);
+
+  // add callbacks to enable restarts
+  atom->add_callback(0);
+  atom->add_callback(1);
+
+  energy = 0.0;
+}
+
+
+/* --- Frees up memory used by temporaries and buffers ------------------ */
+
+FixFFL::~FixFFL() {
+  delete random;
+
+  memory->destroy(sqrt_m);
+  memory->destroy(ffl_tmp1);
+  memory->destroy(ffl_tmp2);
+}
+
+/* ---------------------------------------------------------------------- */
+
+int FixFFL::setmask() {
+  int mask = 0;
+
+  mask |= INITIAL_INTEGRATE;
+  mask |= FINAL_INTEGRATE;
+  mask |= INITIAL_INTEGRATE_RESPA;
+  mask |= FINAL_INTEGRATE_RESPA;
+  mask |= THERMO_ENERGY;
+
+
+  return mask;
+}
+
+/* ------- Initializes one-time quantities for FFL ---------------------- */
+
+void FixFFL::init() {
+  doffl = 1;
+  dtv = update->dt;
+  dtf = 0.5 * update->dt * force->ftm2v;
+
+  // set force prefactors
+  if (!atom->rmass) {
+    for (int i = 1; i <= atom->ntypes; i++) {
+      sqrt_m[i] = sqrt(atom->mass[i]);
+    }
+  }
+
+  if (strstr(update->integrate_style,"respa")) {
+    nlevels_respa = ((Respa *) update->integrate)->nlevels;
+    step_respa = ((Respa *) update->integrate)->step;
+  }
+
+  init_ffl();
+}
+
+/* ------- Initializes constants for FFL (change with T and dt) ------- */
+
+void FixFFL::init_ffl() {
+  const double kT = t_target * force->boltz / force->mvv2e;
+
+  // compute constants for FFL
+
+  c1 = exp ( - gamma * 0.5 * dtv );
+  c2 = sqrt( (1.0 - c1*c1)* kT ); //without the mass term
+
+
+}
+
+
+
+/* ---------------------------------------------------------------------- */
+
+void FixFFL::setup(int vflag) {
+  if (strstr(update->integrate_style,"verlet"))
+    post_force(vflag);
+  else {
+    ((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1);
+    post_force_respa(vflag,nlevels_respa-1,0);
+    ((Respa *) update->integrate)->copy_f_flevel(nlevels_respa-1);
+  }
+}
+
+void FixFFL::ffl_integrate() {
+  double **v = atom->v;
+  double *rmass = atom->rmass, smi, ismi;
+  double factor;
+  int *type = atom->type;
+  int *mask = atom->mask;
+  int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+  // loads momentum data (mass-scaled) into the temporary vectors for the propagation
+  int nk=0;
+  double deltae=0.0;
+  for (int i = 0; i < nlocal; i++) {
+    if (mask[i] & groupbit) {
+      if (rmass) smi = sqrt(rmass[i]);
+      else smi = sqrt_m[type[i]];
+
+      for (int k = 0; k<3; k++) {
+        // first loads velocities and accumulates conserved quantity
+        ffl_tmp2[nk] = v[i][k] * smi;
+        deltae += ffl_tmp2[nk] * ffl_tmp2[nk];
+        nk++;
+      }
+    }
+  }
+
+  //fills up a vector of random numbers
+  for (int i = 0; i < nk; i++) ffl_tmp1[i] = random->gaussian();
+
+
+  // unloads momentum data (mass-scaled) from the temporary vectors
+  nk=0;
+  for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) {
+      if (rmass) ismi = 1.0 / sqrt(rmass[i]);
+      else ismi = 1.0/ sqrt_m[type[i]];
+
+      for (int k = 0; k<3; k++) {
+        // fetches new velocities and completes computation of the conserved quantity change
+        v[i][k]= c1*v[i][k] + c2*ffl_tmp1[nk]*ismi;
+
+        deltae-= v[i][k]*v[i][k] /ismi /ismi;
+
+        //flips the sign of the momentum (HARD FLIP)
+        if ( flip_int == FLIP_HARD) {
+          if (v[i][k]*ffl_tmp2[nk] < 0.0) v[i][k] = -v[i][k];
+        }
+
+        nk++;
+      }
+    }
+
+  //rescale operation (RESCALE FLIP)
+  if (flip_int == FLIP_RESCALE) {
+    nk=0;
+    for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) {
+      factor = sqrt ((v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) /
+                       (ffl_tmp2[nk]*ffl_tmp2[nk] + ffl_tmp2[nk+1]*ffl_tmp2[nk+1]
+                        + ffl_tmp2[nk+2]*ffl_tmp2[nk+2]));
+
+      for (int k = 0; k<3; k++) {
+        v[i][k]= factor * ffl_tmp2[nk];
+        nk++;
+      }
+    }
+  }
+
+
+  //soft flip operation (SOFT FLIP)
+  if (flip_int == FLIP_SOFT) {
+    nk=0;
+    for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) {
+      factor = v[i][0]*ffl_tmp2[nk] + v[i][1]*ffl_tmp2[nk+1] + v[i][2]*ffl_tmp2[nk+2];
+      if (factor < 0) {
+        factor =  factor / (ffl_tmp2[nk]*ffl_tmp2[nk] + ffl_tmp2[nk+1]*ffl_tmp2[nk+1]
+                            + ffl_tmp2[nk+2]*ffl_tmp2[nk+2]);
+
+        for (int k = 0; k<3; k++) {
+          v[i][k] -= 2.0 * factor * ffl_tmp2[nk];
+          nk++;
+        }
+      } else {
+        nk += 3;
+      }
+    }
+
+  }
+
+  energy += deltae*0.5*force->mvv2e;
+
+}
+
+void FixFFL::initial_integrate(int vflag) {
+  double dtfm;
+
+  // update v and x of atoms in group
+  double **x = atom->x;
+  double **v = atom->v;
+  double **f = atom->f;
+  double *rmass = atom->rmass;
+  double *mass = atom->mass;
+  int *type = atom->type;
+  int *mask = atom->mask;
+  int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+  ffl_step--;
+  if (doffl && ffl_step<1) ffl_integrate();
+
+  if (rmass) {
+    for (int i = 0; i < nlocal; i++)
+      if (mask[i] & groupbit) {
+        dtfm = dtf / rmass[i];
+        v[i][0] += dtfm * f[i][0];
+        v[i][1] += dtfm * f[i][1];
+        v[i][2] += dtfm * f[i][2];
+        x[i][0] += dtv * v[i][0];
+        x[i][1] += dtv * v[i][1];
+        x[i][2] += dtv * v[i][2];
+      }
+
+  } else {
+    for (int i = 0; i < nlocal; i++)
+      if (mask[i] & groupbit) {
+        dtfm = dtf / mass[type[i]];
+        v[i][0] += dtfm * f[i][0];
+        v[i][1] += dtfm * f[i][1];
+        v[i][2] += dtfm * f[i][2];
+        x[i][0] += dtv * v[i][0];
+        x[i][1] += dtv * v[i][1];
+        x[i][2] += dtv * v[i][2];
+      }
+  }
+}
+
+void FixFFL::final_integrate() {
+  double dtfm;
+
+  // update v of atoms in group
+
+  double **v = atom->v;
+  double **f = atom->f;
+  double *rmass = atom->rmass;
+  double *mass = atom->mass;
+  int *type = atom->type;
+  int *mask = atom->mask;
+  int nlocal = atom->nlocal;
+  if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+  if (rmass) {
+    for (int i = 0; i < nlocal; i++)
+      if (mask[i] & groupbit) {
+        dtfm = dtf / rmass[i];
+        v[i][0] += dtfm * f[i][0];
+        v[i][1] += dtfm * f[i][1];
+        v[i][2] += dtfm * f[i][2];
+      }
+
+  } else {
+    for (int i = 0; i < nlocal; i++)
+      if (mask[i] & groupbit) {
+        dtfm = dtf / mass[type[i]];
+        v[i][0] += dtfm * f[i][0];
+        v[i][1] += dtfm * f[i][1];
+        v[i][2] += dtfm * f[i][2];
+      }
+  }
+
+  if (doffl && ffl_step<1) {
+    ffl_integrate();
+    ffl_step = ffl_every;
+  }
+
+  // Change the temperature for the next step
+  double delta = update->ntimestep - update->beginstep;
+  delta /= update->endstep - update->beginstep;
+  t_target = t_start + delta * (t_stop - t_start);
+  if (t_stop != t_start) {
+    // only updates if it is really necessary
+    init_ffl();
+  }
+
+}
+/* ---------------------------------------------------------------------- */
+
+void FixFFL::initial_integrate_respa(int vflag, int ilevel, int iloop) {
+  dtv = step_respa[ilevel];
+  dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
+
+  // innermost level - NVE update of v and x
+  // all other levels - NVE update of v
+
+  if (ilevel==nlevels_respa-1) ffl_integrate();
+  doffl=0;
+  if (ilevel == 0) initial_integrate(vflag);
+  else {
+    final_integrate();
+  }
+}
+
+void FixFFL::final_integrate_respa(int ilevel, int iloop) {
+
+  dtv = step_respa[ilevel];
+  dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
+  doffl=0;
+  final_integrate();
+  if (ilevel==nlevels_respa-1) ffl_integrate();
+}
+
+
+double FixFFL::compute_scalar() {
+
+  double energy_me = energy;
+  double energy_all;
+  MPI_Allreduce(&energy_me,&energy_all,1,MPI_DOUBLE,MPI_SUM,world);
+
+  return energy_all;
+}
+
+/* ----------------------------------------------------------------------
+   extract thermostat properties
+------------------------------------------------------------------------- */
+
+void *FixFFL::extract(const char *str, int &dim) {
+  dim = 0;
+  if (strcmp(str,"t_target") == 0) {
+    return &t_target;
+  }
+  return NULL;
+}
+
+
+/* ----------------------------------------------------------------------
+   Called when a change to the target temperature is requested mid-run
+------------------------------------------------------------------------- */
+
+void FixFFL::reset_target(double t_new) {
+
+  t_target = t_start = t_stop = t_new;
+}
+
+/* ----------------------------------------------------------------------
+   Called when a change to the timestep is requested mid-run
+------------------------------------------------------------------------- */
+
+void FixFFL::reset_dt() {
+  // set the time integration constants
+  dtv = update->dt;
+  dtf = 0.5 * update->dt * (force->ftm2v);
+  init_ffl();
+}
+
+/* ----------------------------------------------------------------------
+   memory usage of local atom-based arrays
+------------------------------------------------------------------------- */
+
+double FixFFL::memory_usage() {
+  double bytes = atom->nmax*(3*2)*sizeof(double);
+  return bytes;
+}
+
+
+/* ----------------------------------------------------------------------
+   allocate local atom-based arrays
+------------------------------------------------------------------------- */
+
+void FixFFL::grow_arrays(int nmax) {
+  memory->grow(ffl_tmp1, nmax*3,"ffl:tmp1");
+  memory->grow(ffl_tmp2, nmax*3,"ffl:tmp2");
+  //zeroes out temporary buffers
+  for (int i=0; i< nmax*3; ++i) ffl_tmp1[i] = 0.0;
+  for (int i=0; i< nmax*3; ++i) ffl_tmp2[i] = 0.0;
+}
+
+
diff --git a/src/USER-MISC/fix_ffl.h b/src/USER-MISC/fix_ffl.h
new file mode 100644
index 0000000000000000000000000000000000000000..1225d2598940e5a57208f73f0b4d24568abe0c92
--- /dev/null
+++ b/src/USER-MISC/fix_ffl.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- ----------------------------------------------------------
+   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+   http://lammps.sandia.gov, Sandia National Laboratories
+   Steve Plimpton, sjplimp@sandia.gov
+
+   Copyright (2003) Sandia Corporation.  Under the terms of Contract
+   DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+   certain rights in this software.  This software is distributed under
+   the GNU General Public License.
+
+   See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(ffl,FixFFL)
+
+#else
+
+#ifndef LMP_FIX_FFL_H
+#define LMP_FIX_FFL_H
+
+#include "fix.h"
+
+namespace LAMMPS_NS {
+
+class FixFFL : public Fix {
+ public:
+  FixFFL(class LAMMPS *, int, char **);
+  virtual ~FixFFL();
+  int setmask();
+  void init();
+  void setup(int);
+  void ffl_integrate();
+  void initial_integrate_respa(int vflag, int ilevel, int iloop);
+  void final_integrate_respa(int ilevel, int iloop);
+  void initial_integrate(int vflag);
+  void final_integrate();
+  double compute_scalar();
+  void reset_target(double);
+  virtual void reset_dt();
+  double memory_usage();
+  void grow_arrays(int);
+
+  virtual void *extract(const char *, int &);
+
+  void init_ffl();
+ protected:
+  double *ffl_tmp1, *ffl_tmp2;
+  double t_start, t_stop, t_target;
+  double dtv, dtf, c1, c2, gamma;
+  char flip_type[10];
+
+  int doffl, ffl_every, ffl_step, flip_int;
+  class RanMars *random;
+  double *sqrt_m;
+  double *step_respa;
+  double energy;
+  int nlevels_respa;
+
+  double **vaux;
+};
+
+}
+
+#endif
+#endif