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

#ifndef _MODEL_PROCESSORX_H_
#define _MODEL_PROCESSORX_H_

#define RIFTINFOSIZE 12

#include "../../classes/classes.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 CreateParametersAutodiff(Parameters** pparameters,IoModel* iomodel,int solution_type,int analysis_type);
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 CreateParametersHydrologyShreve(Parameters** pparameters,IoModel* iomodel,int solution_type,int analysis_type);
void CreateParametersHydrologyDCInefficient(Parameters** pparameters,IoModel* iomodel,int solution_type,int analysis_type);
void CreateParametersHydrologyDCEfficient(Parameters** pparameters,IoModel* iomodel,int solution_type,int analysis_type);
void UpdateElementsAndMaterialsControl(Elements* elements,Materials* materials, IoModel* iomodel);
void CreateNodes(Nodes** pnodes, IoModel* iomodel,int analysis,int finite_element,int approximation=NoneApproximationEnum);

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

/*stressbalance horizontal*/
void CreateNodesStressbalance(Nodes** pnodes,IoModel* iomodel);
void CreateConstraintsStressbalance(Constraints** pconstraints,IoModel* iomodel);
void CreateLoadsStressbalance(Loads** ploads, IoModel* iomodel);
void UpdateElementsStressbalance(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*stressbalance vertical*/
void CreateNodesStressbalanceVertical(Nodes** pnodes,IoModel* iomodel);
void CreateConstraintsStressbalanceVertical(Constraints** pconstraints,IoModel* iomodel);
void CreateLoadsStressbalanceVertical(Loads** ploads, IoModel* iomodel);
void UpdateElementsStressbalanceVertical(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*stressbalance SIA*/
void CreateNodesStressbalanceSIA(Nodes** pnodes,IoModel* iomodel);
void CreateConstraintsStressbalanceSIA(Constraints** pconstraints,IoModel* iomodel);
void CreateLoadsStressbalanceSIA(Loads** ploads, IoModel* iomodel);
void UpdateElementsStressbalanceSIA(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

#ifdef _HAVE_GIA_
/*gia*/
void CreateNodesGia(Nodes** pnodes,IoModel* iomodel);
void CreateConstraintsGia(Constraints** pconstraints,IoModel* iomodel);
void CreateLoadsGia(Loads** ploads, IoModel* iomodel);
void UpdateElementsGia(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
#endif

/*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 Shreve:*/
void CreateNodesHydrologyShreve(Nodes** pnodes,IoModel* iomodel);
void CreateConstraintsHydrologyShreve(Constraints** pconstraints,IoModel* iomodel);
void CreateLoadsHydrologyShreve(Loads** ploads, IoModel* iomodel);
void UpdateElementsHydrologyShreve(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);

/*hydrology DC:*/
void CreateNodesHydrologyDCInefficient(Nodes** pnodes,IoModel* iomodel);
void CreateConstraintsHydrologyDCInefficient(Constraints** pconstraints,IoModel* iomodel);
void CreateLoadsHydrologyDCInefficient(Loads** ploads, IoModel* iomodel);
void UpdateElementsHydrologyDCInefficient(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
void CreateNodesHydrologyDCEfficient(Nodes** pnodes,IoModel* iomodel);
void CreateConstraintsHydrologyDCEfficient(Constraints** pconstraints,IoModel* iomodel);
void CreateLoadsHydrologyDCEfficient(Loads** ploads, IoModel* iomodel);
void UpdateElementsHydrologyDCEfficient(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);

/*masstransport:*/
void CreateNodesMasstransport(Nodes** pnodes,IoModel* iomodel);
void CreateConstraintsMasstransport(Constraints** pconstraints,IoModel* iomodel);
void CreateLoadsMasstransport(Loads** ploads, IoModel* iomodel);
void UpdateElementsMasstransport(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
void CreateNodesFreeSurfaceTop(Nodes** pnodes,IoModel* iomodel);
void CreateConstraintsFreeSurfaceTop(Constraints** pconstraints,IoModel* iomodel);
void CreateLoadsFreeSurfaceTop(Loads** ploads, IoModel* iomodel);
void UpdateElementsFreeSurfaceTop(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type);
void CreateNodesFreeSurfaceBase(Nodes** pnodes,IoModel* iomodel);
void CreateConstraintsFreeSurfaceBase(Constraints** pconstraints,IoModel* iomodel);
void CreateLoadsFreeSurfaceBase(Loads** ploads, IoModel* iomodel);
void UpdateElementsFreeSurfaceBase(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);

/*balancedvelocity:*/
void CreateNodesBalancevelocity(Nodes** pnodes,IoModel* iomodel);
void CreateConstraintsBalancevelocity(Constraints** pconstraints,IoModel* iomodel);
void CreateLoadsBalancevelocity(Loads** ploads, IoModel* iomodel);
void UpdateElementsBalancevelocity(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);
void FacesPartitioning(bool** pmy_faces,IoModel* iomodel);
void EdgesPartitioning(bool** pmy_edges,IoModel* iomodel);

/*Mesh properties*/
void CreateFaces(IoModel* iomodel);
void CreateEdges(IoModel* iomodel);

/*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,int node_type);

#endif
