package de.jtem.jtao;

import de.jtem.jpetsc.MPI;
import de.jtem.jpetsc.MPIRunnAndSerializable;
import de.jtem.jpetsc.Vec;
import de.jtem.jpetsc.farm.LocalMPIFarm;
import de.jtem.jtao.Tao.GetSolutionStatusResult;



public class TestTaoMPI implements MPIRunnAndSerializable {
	/**
	 *
	 */
	private static final long serialVersionUID = 796505995382410717L;

	public static class Stopwatch {
	    private long start;
	    private long stop;

	    public void start() {
	        start = System.currentTimeMillis(); // start timing
	    }

	    public void stop(String out) {
	        stop = System.currentTimeMillis(); // stop timing
			System.out.println(out+ " : " +elapsedTimeMillis());
	    }

	    public long elapsedTimeMillis() {
	        return stop - start;
	    }

	    public String toString() {
	        return "elapsedTimeMillis: " + Long.toString(elapsedTimeMillis()); // print execution time
	    }
	}

	public static void main(String[] args){
		LocalMPIFarm mpifarm = new LocalMPIFarm(4);

		mpifarm.run(new TestTaoMPI());
		mpifarm.finish();
	}

	public void run(MPI mpi, int rank){
		Tao.Initialize(null, null, true);

		Tao t = new Tao(mpi.getEveryoneComm(), Tao.Method.CG);

		TaoHeavyApplication app = new TaoHeavyApplication(mpi.getEveryoneComm(), 50000);
		t.setGradientTolerances(0, 0, 0);
		t.setTolerances(0, 0, 0, 0);
		t.setApplication(app);

		Stopwatch w = new Stopwatch();
		w.start();
//		t.testGradient(app.getSolutionVec(), true);
		t.solve();
		w.stop("solved in");

		GetSolutionStatusResult res = t.getSolutionStatus();

		System.out.println(res.toString());

		Vec v = app.getSolutionVec();

		System.out.println("getting global");
		double erg[] = v.getGlobalArray(mpi.getEveryoneComm(), 0, null);
		if(rank == 0){
			System.out.printf("x_0 = " + erg[0]  + "\n");
			System.out.printf("x_"+(erg.length-1)+" = " + erg[erg.length-1]  + "\n");
		}
		System.out.printf("value = " + res.f + "\n");
//		Tao.Finalize();
	}

}