#ifndef COOLFluiD_LES_LES3DCons_hh
#define COOLFluiD_LES_LES3DCons_hh

//////////////////////////////////////////////////////////////////////////////

#include "LES3DVarSet.hh"

//////////////////////////////////////////////////////////////////////////////

namespace COOLFluiD {

    namespace Physics {
      namespace NavierStokes {
        class EulerTerm;
      }
    }

  namespace LES {

//////////////////////////////////////////////////////////////////////////////

  /**
   * This class represents a 3D Large Eddy Simulation physical model for conservative variables
   *
   * @author Kris Van den Abeele
   */
class LES3DCons : public LES3DVarSet {
public: // classes

  /**
   * Constructor
   * @see LES2D
   */
  LES3DCons(const std::string& name, Common::SafePtr<Framework::PhysicalModelImpl> model);

  /**
   * Default destructor
   */
  ~LES3DCons();

  /**
   * Set the composition
   * @pre this function has to be called before any other function
   *      computing other physical quantities
   */
  void setComposition(const RealVector& state,
                      const bool isPerturb,
                      const CFuint iVar)
  {
  }

  /**
   * Set the quantities needed to compute gradients (pressure,
   * velocity, etc.) starting from the states
   */
  void setGradientVars(const std::vector<RealVector*>& states,
                       RealMatrix& values,
                       const CFuint stateSize);

  /**
   * Compute required gradients (velocity, Temperature) starting from the gradients of the states
   */
      void setGradientVarGradients(const std::vector<RealVector*>& states,
                                   const std::vector< std::vector<RealVector*> >& stateGradients,
                                   std::vector< std::vector<RealVector*> >& gradVarGradients,
                                   const CFuint stateSize);

  /**
   * Compute the gradients of the states starting from gradient variable gradients (pressure, velocity, temperature)
   */
      void setStateGradients(const std::vector<RealVector*>& states,
                             const std::vector< std::vector<RealVector*> >& gradVarGradients,
                             std::vector< std::vector<RealVector*> >& stateGradients,
                             const CFuint stateSize);

  /**
   * Get the adimensional dynamic viscosity
   */
  CFreal getDynViscosity(const RealVector& state, const std::vector<RealVector*>& gradients);

  /**
   * Get the adimensional density
   */
  CFreal getDensity(const RealVector& state);

  /**
   * Get the adimensional thermal conductivity
   */
  CFreal getThermConductivity(const RealVector& state,
			      const CFreal& dynViscosity)
  {
    if (Framework::PhysicalModelStack::getActive()->getImplementor()->isAdimensional()) {
      return dynViscosity;
    }
    return dynViscosity*getModel().getCpOverPrandtl();
  }

protected:

  /**
   * Set the gradient variables starting from state variables
   */
  virtual void setGradientState(const RealVector& state);

}; // end of class LES3DCons

//////////////////////////////////////////////////////////////////////////////

    } // namespace LES

} // namespace COOLFluiD

//////////////////////////////////////////////////////////////////////////////

#endif // COOLFluiD_LES_LES3DCons_hh
