/* \file ModelProcessorx.h
 * \brief  Header file for model processor
 */

#ifndef _MODEL_PROCESSORX_H_
#define _MODEL_PROCESSORX_H_

#define RIFTINFOSIZE 12

class DataSet;
class IoModel;
class Parameters;
class DofIndexing;

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

void ModelProcessorx(Elements** pelements, Nodes** pnodes, Vertices** pvertices, Materials** pmaterials, Constraints** pconstraints, Loads** ploads, Parameters** pparameters, FILE* iomodel_handle,char* rootpath,const int solution_type,const int nummodels,const int* analysis_type_listh);

/*Creation of fem datasets: general drivers*/
void  CreateDataSets(Elements** pelements,Nodes** pnodes,Vertices** pvertices, Materials** pmaterials, Constraints** pconstraints, Loads** ploads,Parameters** pparameters,IoModel* iomodel,char* rootpath,const int solution_type,int analysis_type,const int nummodels,int analysis_counter);
void  CreateElementsVerticesAndMaterials(Elements** pelements,Vertices** pvertices,Materials** pmaterials, IoModel* iomodel,const int nummodels);
void  CreateParameters(Parameters** pparameters,IoModel* iomodel,char* rootpath,const int solution_type,int analysis_type,int analysis_counter);
void  CreateParametersControl(Parameters** pparameters,IoModel* iomodel,int solution_type,int analysis_type);
void  CreateParametersDakota(Parameters** pparameters,IoModel* iomodel,char* rootpath,int solution_type,int analysis_type);
void  CreateParametersAutodiff(Parameters** pparameters,IoModel* iomodel,int solution_type,int analysis_type);
void  UpdateElementsAndMaterialsControl(Elements* elements,Materials* materials, IoModel* iomodel);

/*Creation of fem datasets: specialised drivers: */

/*diagnostic horizontal*/
void	CreateNodesDiagnosticHoriz(Nodes** pnodes,IoModel* iomodel);
void	CreateConstraintsDiagnosticHoriz(Constraints** pconstraints,IoModel* iomodel);
void  CreateLoadsDiagnosticHoriz(Loads** ploads, IoModel* iomodel);
void	UpdateElementsDiagnosticHoriz(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*diagnostic vertical*/
void	CreateNodesDiagnosticVert(Nodes** pnodes,IoModel* iomodel);
void	CreateConstraintsDiagnosticVert(Constraints** pconstraints,IoModel* iomodel);
void  CreateLoadsDiagnosticVert(Loads** ploads, IoModel* iomodel);
void	UpdateElementsDiagnosticVert(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*diagnostic hutter*/
void	CreateNodesDiagnosticHutter(Nodes** pnodes,IoModel* iomodel);
void	CreateConstraintsDiagnosticHutter(Constraints** pconstraints,IoModel* iomodel);
void  CreateLoadsDiagnosticHutter(Loads** ploads, IoModel* iomodel);
void	UpdateElementsDiagnosticHutter(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*bed slope*/
void	CreateNodesBedSlope(Nodes** pnodes,IoModel* iomodel);
void	CreateConstraintsBedSlope(Constraints** pconstraints,IoModel* iomodel);
void  CreateLoadsBedSlope(Loads** ploads, IoModel* iomodel);
void	UpdateElementsBedSlope(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*surface slope*/
void	CreateNodesSurfaceSlope(Nodes** pnodes,IoModel* iomodel);
void	CreateConstraintsSurfaceSlope(Constraints** pconstraints,IoModel* iomodel);
void  CreateLoadsSurfaceSlope(Loads** ploads, IoModel* iomodel);
void	UpdateElementsSurfaceSlope(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*thermal:*/
void	CreateNodesThermal(Nodes** pnodes,IoModel* iomodel);
void	CreateConstraintsThermal(Constraints** pconstraints,IoModel* iomodel);
void  CreateLoadsThermal(Loads** ploads, IoModel* iomodel);
void	UpdateElementsThermal(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*enthalpy:*/
void	CreateNodesEnthalpy(Nodes** pnodes,IoModel* iomodel);
void	CreateConstraintsEnthalpy(Constraints** pconstraints,IoModel* iomodel);
void  CreateLoadsEnthalpy(Loads** ploads, IoModel* iomodel);
void	UpdateElementsEnthalpy(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*hydrology:*/
void	CreateNodesHydrology(Nodes** pnodes,IoModel* iomodel);
void	CreateConstraintsHydrology(Constraints** pconstraints,IoModel* iomodel);
void  CreateLoadsHydrology(Loads** ploads, IoModel* iomodel);
void	UpdateElementsHydrology(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*melting:*/
void	CreateNodesMelting(Nodes** pnodes,IoModel* iomodel);
void	CreateConstraintsMelting(Constraints** pconstraints,IoModel* iomodel);
void  CreateLoadsMelting(Loads** ploads, IoModel* iomodel);
void	UpdateElementsMelting(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*prognostic:*/
void	CreateNodesPrognostic(Nodes** pnodes,IoModel* iomodel);
void	CreateConstraintsPrognostic(Constraints** pconstraints,IoModel* iomodel);
void  CreateLoadsPrognostic(Loads** ploads, IoModel* iomodel);
void	UpdateElementsPrognostic(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*balancedthickness:*/
void	CreateNodesBalancethickness(Nodes** pnodes,IoModel* iomodel);
void	CreateConstraintsBalancethickness(Constraints** pconstraints,IoModel* iomodel);
void  CreateLoadsBalancethickness(Loads** ploads, IoModel* iomodel);
void	UpdateElementsBalancethickness(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*transient: */
void	UpdateElementsTransient(Elements* elements,Parameters* parameters,IoModel* iomodel,int analysis_counter,int analysis_type);

/*partitioning: */
void  ElementsAndVerticesPartitioning(bool** pmy_elements, int** pmy_vertices, IoModel* iomodel);
void  NodesPartitioning(bool** pmy_nodes,bool* my_elements, int* my_vertices,  IoModel* iomodel, bool continuous);

/*Connectivity*/
void  CreateSingleNodeToElementConnectivity(IoModel* iomodel);
void  CreateNumberNodeToElementConnectivity(IoModel* iomodel);

/*Diverse: */
void  SortDataSets(Elements** pelements,Nodes** pnodes,Vertices** pvertices, Loads** ploads, Materials** pmaterials, Constraints** pconstraints, Parameters** pparameters);
void  UpdateCounters(IoModel* iomodel,Nodes** pnodes,Loads** ploads, Constraints** pconstraints);

/*Distribution of dofs: */
void DistributeNumDofs(DofIndexing* index,int analysis_type,IssmDouble* vertices_type);

#endif
