#include "gstate.h" void calc_convex_hull(Array *p_gs_str, const Array &concentration, const Array &energy) { Array gs_str(concentration.get_size()); int nb_in_hull=0; Real cur_concentration=MAXFLOAT; Real cur_energy=MAXFLOAT; int cur_gs; for (int i=0; icur_concentration) { Real slope=(energy(i)-cur_energy)/(concentration(i)-cur_concentration); if (sloperesize(nb_in_hull); for (int i=0; i *p_gs_concentration, Array *p_gs_energy, const Array &concentration, const Array &energy) { Array gs_str; calc_convex_hull(&gs_str, concentration,energy); p_gs_concentration->resize(gs_str.get_size()); p_gs_energy->resize(gs_str.get_size()); for (int i=0; i *p_gs_concentration, Array *p_gs_energy, const Array &gs_str, const Array &concentration, const Array &energy) { p_gs_concentration->resize(gs_str.get_size()); p_gs_energy->resize(gs_str.get_size()); for (int i=0; i *p_problem, const Array &ground_state, const Array &concentration, const Array &fitted_energy, Real minc, Real maxc) { Real minminc=min(concentration); Real maxmaxc=max(concentration); if (mincmaxmaxc) maxc=maxmaxc; int a_problem=0; p_problem->resize(fitted_energy.get_size()); zero_array(p_problem); if (near_zero(maxc-minc)) { int index_min=-1; Real min_energy=MAXFLOAT; for (int str=0; str minc-zero_tolerance) break; } if (!near_zero(concentration(ground_state(gs))-minc)) { (*p_problem)(ground_state(gs))=1; (*p_problem)(ground_state(gs-1))=1; (*p_problem)(index_min)=1; a_problem=1; } else if (index_min!=ground_state(gs)) { (*p_problem)(ground_state(gs))=1; (*p_problem)(index_min)=1; a_problem=1; } } } else { int min_gs; for (min_gs=1; min_gs minc) break; } int max_gs; for (max_gs=ground_state.get_size()-1; max_gs>1; max_gs--) { if (concentration(ground_state(max_gs-1))+zero_tolerance < maxc) break; } for (int gs=min_gs; gs<=max_gs; gs++) { Real c0=concentration(ground_state(gs-1)); Real c1=concentration(ground_state(gs)); Real e0=fitted_energy(ground_state(gs-1)); Real e1=fitted_energy(ground_state(gs)); Real slope=(e1-e0)/(c1-c0); if (gs==min_gs) { e0=e0+slope*(minminc-c0); c0=minminc; } if (gs==max_gs) { e1=e1+slope*(maxmaxc-c1); c1=maxmaxc; } if (gs>=min_gs+1) { Real c_1=concentration(ground_state(gs-2)); Real e_1=fitted_energy(ground_state(gs-2)); if ( (e1-e0)/(c1-c0) < (e0-e_1)/(c0-c_1) ) { (*p_problem)(ground_state(gs-2))=1; (*p_problem)(ground_state(gs-1))=1; (*p_problem)(ground_state(gs))=1; a_problem=1; } } Real a=(c1*e0-c0*e1)/(c1-c0); Real b=(e1-e0)/(c1-c0); for (int str=0; str=c0 && c<=c1) { Real hull_e=a+b*c; if (str!=ground_state(gs-1) && str!=ground_state(gs) && fitted_energy(str)<=hull_e) { (*p_problem)(str)=1; (*p_problem)(ground_state(gs-1))=1; (*p_problem)(ground_state(gs ))=1; a_problem=1; } } } } } return a_problem; } int ground_state_problem(Array *p_problem, const Array &gs_concentration, const Array &gs_energy, const Array &concentration, const Array &energy, Real minc, Real maxc) { if (concentration.get_size()==0) { p_problem->resize(0); return 0; } Real minminc=MIN(min(concentration),min(gs_concentration)); Real maxmaxc=MAX(max(concentration),max(gs_concentration)); if (mincmaxmaxc) maxc=maxmaxc; int a_problem=0; p_problem->resize(energy.get_size()); zero_array(p_problem); if (near_zero(maxc-minc)) { minc-=2*zero_tolerance; maxc+=2*zero_tolerance; } int min_gs; for (min_gs=1; min_gs minc) break; } int max_gs; for (max_gs=gs_concentration.get_size()-1; max_gs>1; max_gs--) { if (gs_concentration(max_gs-1)+zero_tolerance < maxc) break; } for (int gs=min_gs; gs<=max_gs; gs++) { Real c0=gs_concentration(gs-1); Real c1=gs_concentration(gs); Real e0=gs_energy(gs-1); Real e1=gs_energy(gs); Real slope=(e1-e0)/(c1-c0); if (gs==min_gs) { e0=e0+slope*(minminc-c0); c0=minminc; } if (gs==max_gs) { e1=e1+slope*(maxmaxc-c1); c1=maxmaxc; } Real a=(c1*e0-c0*e1)/(c1-c0); Real b=(e1-e0)/(c1-c0); for (int str=0; strc0 && c *p_form_value, const Array &concentration, const Array &value, Real *e_c0, Real *e_c1) { Real pure_A=MAXFLOAT; Real pure_B=MAXFLOAT; if (e_c0 && e_c1 && (*e_c0)!=MAXFLOAT && (*e_c1)!=MAXFLOAT) { pure_A=*e_c0; pure_B=*e_c1; } else { Real minc=min(concentration); Real maxc=max(concentration); Real mince,maxce; for (int i=0; iresize(value.get_size()); Real a=(pure_B+pure_A)/2.; Real b=(pure_B-pure_A)/2.; for (int i=0; i *hull_energy, const Array &ground_state, const Array &concentration, const Array &energy) { hull_energy->resize(energy.get_size()); for (int gs=1; gs=c0 && c<=c1) { (*hull_energy)(str)=a+b*c; } } } }