//#####################################################################
// Copyright 2004-2007, Ron Fedkiw, Geoffrey Irving, Andrew Selle.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Class SOLIDS_DRIVER
//#####################################################################
#ifndef __SOLIDS_DRIVER__
#define __SOLIDS_DRIVER__    

#include <Core/Arrays/FACE_ARRAYS.h>
#include <Core/Ordinary_Differential_Equations/RUNGEKUTTA.h>
#include <Solids/Examples_And_Drivers/DRIVER.h>
#include <Solids/Examples_And_Drivers/SOLIDS_EXAMPLE.h>
namespace PhysBAM{

template<class TV>
class SOLIDS_DRIVER:public DRIVER<TV>
{
    typedef VECTOR<int,TV::m> IV;typedef typename TV::SCALAR T;typedef VECTOR<T,TV::m+2> TV_DIMENSION;
    typedef ARRAY<TV_DIMENSION,IV> T_ARRAYS_DIMENSION_SCALAR;
    typedef DRIVER<TV> BASE;
public:
    using BASE::time;using BASE::current_frame;
    SOLIDS_EXAMPLE<TV>& example;
    T next_dt; // for fluid time stepping
    bool next_done; // for fluid time stepping
    T last_dt;
    T restart_dt;
    bool reset_with_restart;

    SOLIDS_DRIVER(SOLIDS_EXAMPLE<TV>& example_input);
    virtual ~SOLIDS_DRIVER();

//#####################################################################
    virtual void Preprocess_Frame(const int frame);
    void Execute_Main_Program() override;
    void Simulate_To_Frame(const int frame_input) override;
    void Initialize() override;
    void Advance_To_Target_Time(const T target_time) override;
    void Postprocess_Frame(const int frame);
    T Compute_Dt(const T time,const T target_time,bool& done);
    void Setup_Solids(const T time);
    void Solid_Position_Update(const T dt);
    void Rigid_Cluster_Fracture(const T dt_full_advance,const T dt_cfl);
    void Solid_Velocity_Update(const T dt);
//#####################################################################
};
}
#endif
