/*!\file: solver_adjoint_linear.cpp
 * \brief: numerical core of linear solutions
 */ 

#include "../toolkits/toolkits.h"
#include "../classes/objects/objects.h"
#include "../EnumDefinitions/EnumDefinitions.h"
#include "../modules/modules.h"

void solver_adjoint_linear(FemModel* femmodel){
	/*This is axactly the same solver as solver_linear except that Reduceloadfromgtofx and Mergesolutionfromftogx
	 * use the flag "true" so that all spc are taken as 0*/

	/*intermediary: */
	Matrix*  Kff = NULL;
	Matrix*  Kfs = NULL;
	Vector*  ug  = NULL;
	Vector*  uf  = NULL;
	Vector*  pf  = NULL;
	Vector*  df  = NULL;
	Vector*  ys  = NULL;
	int  configuration_type;

	/*Recover parameters: */
	femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum);
	UpdateConstraintsx(femmodel->nodes,femmodel->constraints,femmodel->parameters);

	SystemMatricesx(&Kff, &Kfs, &pf, &df, NULL,femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters);
	CreateNodalConstraintsx(&ys,femmodel->nodes,configuration_type);
	Reduceloadx(pf, Kfs, ys,true); xdelete(&Kfs); //true means spc = 0
	Solverx(&uf, Kff, pf, NULL, df, femmodel->parameters); xdelete(&Kff); xdelete(&pf); xdelete(&df);
	Mergesolutionfromftogx(&ug, uf,ys,femmodel->nodes,femmodel->parameters,true); xdelete(&uf);xdelete(&ys); //true means spc0
	InputUpdateFromSolutionx(femmodel->elements,femmodel->nodes, femmodel->vertices, femmodel->loads, femmodel->materials, femmodel->parameters,ug);
	xdelete(&ug); xdelete(&uf);
}
