/*!\file InputConvergencex
 */

#include "./InputConvergencex.h"
#include "../../shared/shared.h"
#include "../../include/include.h"
#include "../../io/io.h"
#include "../../toolkits/toolkits.h"
#include "../../EnumDefinitions/EnumDefinitions.h"

bool InputConvergencex(Elements* elements,Nodes* nodes,Vertices* vertices,Loads* loads,Materials* materials,Parameters* parameters,int* enums, int num_enums, int* criterionenums, IssmDouble* criterionvalues,int num_criterionenums){

	/*intermediary:*/
	int      i;
	bool     converged;
	int      num_notconverged   = 0;
	int      total_notconverged;
	IssmDouble  *eps                = NULL;
	Element *element            = NULL;

	/*allocate dynamic memory: */
	eps=xNew<IssmDouble>(num_criterionenums);

	/*Go through elements, and ask them to do the job: */
	for(i=0;i<elements->Size();i++){
		element=dynamic_cast<Element*>(elements->GetObjectByOffset(i));
		converged=element->InputConvergence(eps,enums,num_enums,criterionenums,criterionvalues,num_criterionenums);
		if(!converged) num_notconverged++;
	}

	/*In parallel, we need to gather the converged status: */
	#ifdef _HAVE_MPI_
	MPI_Allreduce ( (void*)&num_notconverged,(void*)&total_notconverged,1,MPI_INT,MPI_SUM,IssmComm::GetComm());
	num_notconverged=total_notconverged;
	#endif
	if(VerboseConvergence()) _pprintLine_("      #elements above convergence criterion = " << num_notconverged);

	/*Free ressources:*/
	xDelete<IssmDouble>(eps);

	/*return: */
	if (num_notconverged){
		return false;}
	else{
		return true;}
}
