// Copyright (C) 2016 EDF
// All Rights Reserved
// This code is published under the GNU Lesser General Public License (GNU LGPL)
#include "StOpt/semilagrangien/SimulateStepSemilagrangControl.h"
#include "StOpt/core/utils/eigenGeners.h"
#include "StOpt/core/grids/FullGridGeners.h"
#include "StOpt/core/grids/RegularSpaceGridGeners.h"
#include "StOpt/core/grids/GeneralSpaceGridGeners.h"
#include "StOpt/core/grids/SparseSpaceGridNoBoundGeners.h"
#include "StOpt/core/grids/SparseSpaceGridBoundGeners.h"

using namespace std;
using namespace StOpt;
using namespace Eigen;

SimulateStepSemilagrangControl::SimulateStepSemilagrangControl(gs::BinaryFileArchive &p_ar,  const int &p_iStep,  const string &p_name,
        const  shared_ptr<SpaceGrid>   &p_gridCur, const shared_ptr<SpaceGrid>   &p_gridNext,
        const  shared_ptr<StOpt::OptimizerSLBase > &p_pOptimize):
    m_gridNext(p_gridNext), m_controlInterp(p_pOptimize->getNbControl()),  m_pOptimize(p_pOptimize)
{
    string valDump = p_name + "Control";
    vector< shared_ptr<ArrayXd > > control;
    gs::Reference<decltype(control)>(p_ar, valDump.c_str(), boost::lexical_cast<string>(p_iStep).c_str()).restore(0, &control);
    for (int iCont = 0; iCont < p_pOptimize->getNbControl(); ++iCont)
        m_controlInterp[iCont] = p_gridCur->createInterpolatorSpectral(*control[iCont]);

}

void SimulateStepSemilagrangControl::oneStep(const ArrayXXd   &p_gaussian, ArrayXXd &p_statevector, ArrayXi &p_iReg, ArrayXXd  &p_phiInOut) const
{

    int is ;
#ifdef _OPENMP
    #pragma omp parallel for  private(is)
#endif
    for (is = 0; is <  p_statevector.cols(); ++is)
    {
        m_pOptimize->stepSimulateControl(*m_gridNext, m_controlInterp, p_statevector.col(is), p_iReg(is), p_gaussian.col(is), p_phiInOut.col(is));
    }

}
