/*
 * cores.h: 
 */

#ifndef _CORES_H_
#define _CORES_H_

/*forward declarations: */
class FemModel;
class Parameters;
class SealevelMasks;
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 adjointbalancethickness2_core(FemModel* femmodel);
void stressbalance_core(FemModel* femmodel);
void hydrology_core(FemModel* femmodel);
void thermal_core(FemModel* femmodel);
void surfaceslope_core(FemModel* femmodel);
void levelsetfunctionslope_core(FemModel* femmodel);
void movingfront_core(FemModel* femmodel);
void groundingline_core(FemModel* femmodel);
void bedslope_core(FemModel* femmodel);
void meshdeformation_core(FemModel* femmodel);
void control_core(FemModel* femmodel);
void controltao_core(FemModel* femmodel);
void controlm1qn3_core(FemModel* femmodel);
void controladm1qn3_core(FemModel* femmodel);
void controlvalidation_core(FemModel* femmodel);
void masstransport_core(FemModel* femmodel);
void depthaverage_core(FemModel* femmodel);
void extrudefrombase_core(FemModel* femmodel);
void extrudefromtop_core(FemModel* femmodel);
void balancethickness_core(FemModel* femmodel);
void balancethickness2_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 adgradient_core(FemModel* femmodel);
void dummy_core(FemModel* femmodel);
void gia_core(FemModel* femmodel);
void love_core(FemModel* femmodel);
void esa_core(FemModel* femmodel);
void smb_core(FemModel* femmodel);
void bmb_core(FemModel* femmodel);
void damage_core(FemModel* femmodel);
void sealevelchange_core(FemModel* femmodel);
void grd_core(FemModel* femmodel);
void dynstr_core(FemModel* femmodel);
void sealevelrise_core_geometry(FemModel* femmodel);
SealevelMasks* sealevelrise_core_masks(FemModel* femmodel);
Vector<IssmDouble>* sealevelrise_core_eustatic(FemModel* femmodel,SealevelMasks* mask, IssmDouble* poceanarea);
Vector<IssmDouble>* sealevelrise_core_noneustatic(FemModel* femmodel,SealevelMasks* masks, Vector<IssmDouble>* RSLg_eustatic,IssmDouble oceanarea);
void sealevelrise_core_elastic(Vector<IssmDouble>** pU_radial, Vector<IssmDouble>** pU_north,Vector<IssmDouble>** pU_east,FemModel* femmodel,Vector<IssmDouble>* RSLg, SealevelMasks* masks);
void sealevelrise_core_viscous(Vector<IssmDouble>** pU_gia,Vector<IssmDouble>** pN_gia,FemModel*  femmodel,Vector<IssmDouble>* RSLg);
void sealevelrise_diagnostics(FemModel* femmodel,Vector<IssmDouble>* RSLg);
IssmDouble objectivefunction(IssmDouble search_scalar,FemModel* femmodel);
void GetStericRate(Vector<IssmDouble> ** psteric_rate_g, FemModel* femmodel);
void GetDynamicRate(Vector<IssmDouble> ** pdynamic_rate_g, FemModel* femmodel);
void SetBottomPressure(FemModel* femmodel);

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

//diverse
void ProcessArguments(int* solution,char** pbinname,char** poutbinname,char** ptoolkitsname,char** plockname,char** prestartname, char** prootpath,char** pmodelname, int argc,char **argv);
void WriteLockFile(char* filename);
void ResetBoundaryConditions(FemModel* femmodel, int analysis_type);
void PrintBanner(void);
void TransferForcing(FemModel* femmodel,int forcingenum);
void TransferSealevel(FemModel* femmodel,int forcingenum);
void EarthMassTransport(FemModel* femmodel);
void slrconvergence(bool* pconverged, Vector<IssmDouble>* RSLg,Vector<IssmDouble>* RSLg_old,IssmDouble eps_rel,IssmDouble eps_abs);

//solution configuration
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
