/*!\file: masstransport_core.cpp
 * \brief: core of the masstransport solution 
 */ 

#include "./analyses.h"
#include "../toolkits/toolkits.h"
#include "../classes/classes.h"
#include "../shared/shared.h"
#include "../modules/modules.h"
#include "../solutionsequences/solutionsequences.h"

void masstransport_core(FemModel* femmodel){

	/*parameters: */
	bool  save_results;
	bool  issmbgradients,ispdd,isdelta18o,isFS,isfreesurface;
	int   solution_type;
	int  *requested_outputs = NULL;
	int   numoutputs        = 0;

	/*activate configuration*/
	femmodel->SetCurrentConfiguration(MasstransportAnalysisEnum);

	/*recover parameters: */
	femmodel->parameters->FindParam(&save_results,SaveResultsEnum);
	femmodel->parameters->FindParam(&issmbgradients,SurfaceforcingsIssmbgradientsEnum);
	femmodel->parameters->FindParam(&ispdd,SurfaceforcingsIspddEnum);
	femmodel->parameters->FindParam(&isdelta18o,SurfaceforcingsIsdelta18oEnum);
	femmodel->parameters->FindParam(&isFS,FlowequationIsFSEnum);
	femmodel->parameters->FindParam(&isfreesurface,MasstransportIsfreesurfaceEnum);
	femmodel->parameters->FindParam(&solution_type,SolutionTypeEnum);
	femmodel->parameters->FindParam(&numoutputs,MasstransportNumRequestedOutputsEnum);
	if(numoutputs) femmodel->parameters->FindParam(&requested_outputs,&numoutputs,MasstransportRequestedOutputsEnum);

	if(issmbgradients){
	  if(VerboseSolution())_printf_("	call smb gradients module\n\n");
	  SmbGradientsx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
	}
	if(ispdd){
		if(isdelta18o){
			if(VerboseSolution()) _printf0_("   call Delta18oParametrization module\n");
			Delta18oParameterizationx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
		} 
		if(VerboseSolution()) _printf0_("   call positive degree day module\n");
		PositiveDegreeDayx(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
	}

	if(isFS && isfreesurface){
		if(VerboseSolution()) _printf0_("   call free surface computational core\n");
		femmodel->SetCurrentConfiguration(FreeSurfaceBaseAnalysisEnum);
		solutionsequence_linear(femmodel);
		femmodel->SetCurrentConfiguration(FreeSurfaceTopAnalysisEnum);
		solutionsequence_linear(femmodel);
	}
	else{
		if(VerboseSolution()) _printf0_("   call computational core\n");
		solutionsequence_linear(femmodel);
	}

	if(save_results){
		if(VerboseSolution()) _printf0_("   saving results\n");
		InputToResultx(femmodel,ThicknessEnum);
		InputToResultx(femmodel,BedEnum);
		InputToResultx(femmodel,SurfaceEnum);
		femmodel->RequestedOutputsx(requested_outputs,numoutputs);
	}

	if(solution_type==MasstransportSolutionEnum)femmodel->RequestedDependentsx();

	/*Free ressources:*/
	xDelete<int>(requested_outputs);
}
