// Copyright (c) 2009-2016 The Regents of the University of Michigan
// This file is part of the HOOMD-blue project, released under the BSD 3-Clause License.


// Maintainer: joaander

#include "IntegrationMethodTwoStep.h"
#include "hoomd/Variant.h"

#ifndef __TWO_STEP_LANGEVIN_BASE__
#define __TWO_STEP_LANGEVIN_BASE__

/*! \file TwoStepLangevinBase.h
    \brief Declares the TwoStepLangevinBase class
*/

#ifdef NVCC
#error This header cannot be compiled by nvcc
#endif

//! Base class for Langevin equation based integration method
/*! HOOMD implements Langevin dynamics and Brownian dynamics. Both are based on the same equation of motion, but the
    latter assumes an overdamped regime while the former assumes underdamped. This base class store and manages
    the data structures and settings that are common to the two of them, including temperature, seed, and gamma.

    \ingroup updaters
*/
class TwoStepLangevinBase : public IntegrationMethodTwoStep
    {
    public:
        //! Constructs the integration method and associates it with the system
        TwoStepLangevinBase(boost::shared_ptr<SystemDefinition> sysdef,
                            boost::shared_ptr<ParticleGroup> group,
                            boost::shared_ptr<Variant> T,
                            unsigned int seed,
                            bool use_lambda,
                            Scalar lambda);
        virtual ~TwoStepLangevinBase();

        //! Set a new temperature
        /*! \param T new temperature to set */
        void setT(boost::shared_ptr<Variant> T)
            {
            m_T = T;
            }

        //! Sets gamma for a given particle type
        void setGamma(unsigned int typ, Scalar gamma);

        void setGamma_r(unsigned int typ, Scalar gamma_r);

    protected:
        boost::shared_ptr<Variant> m_T;   //!< The Temperature of the Stochastic Bath
        unsigned int m_seed;              //!< The seed for the RNG of the Stochastic Bath
        bool m_use_lambda;                //!< flag to enable gamma to be a scaled version of the diameter
        Scalar m_lambda;                  //!< Scale factor to apply to diameter to get gamma

        GPUVector<Scalar> m_gamma;        //!< List of per type gammas to use
        GPUVector<Scalar> m_gamma_r;      //!< List of per type gamma_r (for 2D-only rotational noise) to use

        //! Method to be called when number of types changes
        virtual void slotNumTypesChange();

    private:
        //! Connection to the signal notifying when number of particle types changes
        boost::signals2::connection m_num_type_change_connection;
    };

//! Exports the TwoStepLangevinBase class to python
void export_TwoStepLangevinBase();

#endif // #ifndef __TWO_STEP_LANGEVIN_BASE__
