/*
 * analyses.h: 
 */

#ifndef _ANALYSES_H_
#define _ANALYSES_H_

/*forward declarations: */
struct OptArgs;
class FemModel;
class Parameters;
template <class doubletype> class Matrix;
template <class doubletype> class Vector;

#include "../shared/io/Comm/IssmComm.h"
#include "../shared/Numerics/types.h"

/*cores: */
void adjointstressbalance_core(FemModel* femmodel);
void adjointbalancethickness_core(FemModel* femmodel);
void gradient_core(FemModel* femmodel,int n=0,bool orthogonalize=false);
void stressbalance_core(FemModel* femmodel);
void hydrology_core(FemModel* femmodel);
void thermal_core(FemModel* femmodel);
void enthalpy_core(FemModel* femmodel);
void surfaceslope_core(FemModel* femmodel);
void bedslope_core(FemModel* femmodel);
void control_core(FemModel* femmodel);
void controltao_core(FemModel* femmodel);
void masstransport_core(FemModel* femmodel);
void balancethickness_core(FemModel* femmodel);
void balancevelocity_core(FemModel* femmodel);
void slopecompute_core(FemModel* femmodel);
void steadystate_core(FemModel* femmodel);
void transient_core(FemModel* femmodel);
void dakota_core(FemModel* femmodel);
void ad_core(FemModel* femmodel);
void dummy_core(FemModel* femmodel);
void gia_core(FemModel* femmodel);
IssmDouble objectivefunction(IssmDouble search_scalar,OptArgs* optargs);

//optimization
int GradJSearch(IssmDouble* search_vector,FemModel* femmodel,int step);

//diverse
void ProcessArguments(int* solution,char** pbinname,char** poutbinname,char** ptoolkitsname,char** plockname,char** prootpath,int argc,char **argv);
void WriteLockFile(char* filename);
void ResetBoundaryConditions(FemModel* femmodel, int analysis_type);
ISSM_MPI_Comm EnvironmentInit(int argc,char** argv);
void EnvironmentFinalize(void);
void PrintBanner(void);

//solution configuration
void AnalysisConfiguration(int** panalyses,int* pnumanalyses, int solutiontype);
void CorePointerFromSolutionEnum(void (**psolutioncore)(FemModel*),Parameters* parameters,int solutiontype);
void WrapperCorePointerFromSolutionEnum(void (**psolutioncore)(FemModel*),Parameters* parameters,int solutiontype,bool nodakotacore=false);
void AdjointCorePointerFromSolutionEnum(void (**padjointcore)(FemModel*),int solutiontype);

#endif
