/*\file Solver.c
 *\brief: solver
 */

#include "./Solver.h"

void mexFunction( int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]){

	/*input datasets: */
	Mat         Kff           = NULL;
	Vec         pf            = NULL;
	Vec         uf0           = NULL;
	Vec         uf            = NULL;
	Vec         df            = NULL;
	Parameters *parameters    = NULL;
	int         analysis_type;
	char        option[100];
	#if _PETSC_MAJOR_ < 3 || (_PETSC_MAJOR_ == 3 && _PETSC_MINOR_ < 2)
	PetscTruth  flag;
	#else
	PetscBool flag;
	#endif
	
	/*Matlab solver: */
	mxArray* array[2];

	MODULEBOOT();

	/*checks on arguments on the matlab side: */
	CheckNumMatlabArguments(nlhs,NLHS,nrhs,NRHS,__FUNCT__,&SolverUsage);
	
	/*parameters: */
	FetchMatlabData(&parameters,PARAMETERS);

	/*In serial mode, we have not set any petsc options, do it now: */
	#ifdef _SERIAL_
	parameters->FindParam(&analysis_type,AnalysisTypeEnum);
	PetscOptionsFromAnalysis(parameters,analysis_type);
	#endif
	
	/*Retrieve solver type: */
	PetscOptionsGetString(PETSC_NULL,"-ksp_type",&option[0],100,&flag);

	/*Fetch rest of data only if not running the matlab solver: */
	if (strcmp(option,"matlab")!=0){
	
		/*Input datasets: */
		FetchMatlabData(&Kff,KFF);
		FetchMatlabData(&pf,PF);
		FetchMatlabData(&uf0,UF0);
		FetchMatlabData(&df,DF);

		/*Core module: */
		Solverx(&uf, Kff, pf, uf0, df,parameters);

		/*Write output*/
		WriteMatlabData(UF,uf);
	}
	else{
		/*Matlab solver: */
		if (VerboseModule()) printf("   Solving\n");
		array[0]=KFF;
		array[1]=PF;
		mexCallMATLAB(1,UF,2,array,"mldivide");
	}

	/*Free ressources: */
	MatFree(&Kff);
	VecFree(&pf);
	VecFree(&uf0);
	VecFree(&uf);
	VecFree(&df);
	delete parameters;

	MODULEEND();

}

void SolverUsage(void)
{
	_printf_(true,"\n");
	_printf_(true,"   usage: [uf] = %s(Kff,pf,uf0,df,parameters);\n",__FUNCT__);
	_printf_(true,"\n");
}
