/*
 * solutions.h: 
 */

#ifndef SOLUTIONS_H_
#define SOLUTIONS_H_

#include "../objects/objects.h"
#include "../io/io.h"

struct OptArgs;
class FemModel;

/*cores: */
void adjointdiagnostic_core(FemModel* femmodel);
void adjointbalancethickness_core(FemModel* femmodel);
void gradient_core(FemModel* femmodel,int n=0,bool orthogonalize=false);
void diagnostic_core(FemModel* femmodel);
void hydrology_core(FemModel* femmodel);
void hydrology_core_step(FemModel* femmodel,int step, IssmDouble time);
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 prognostic_core(FemModel* femmodel);
void balancethickness_core(FemModel* femmodel);
void slopecompute_core(FemModel* femmodel);
void steadystate_core(FemModel* femmodel);
void transient_core(FemModel* femmodel);
IssmDouble objectivefunction(IssmDouble search_scalar,OptArgs* optargs);

//convergence:
void convergence(bool* pconverged, Matrix* K_ff,Vector* p_f,Vector* u_f,Vector* u_f_old,Parameters* parameters);
bool controlconvergence(IssmDouble J,IssmDouble tol_cm);
bool steadystateconvergence(FemModel* femmodel);

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

//diverse
void ProcessArguments(int* solution,char** pbinname,char** poutbinname,char** ppetscname,char** plockname,int argc,char **argv);
void WriteLockFile(char* filename);
void controlrestart(FemModel* femmodel,IssmDouble* J);
void ResetBoundaryConditions(FemModel* femmodel, int analysis_type);

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

#endif
