#include "Sundance.h"
#include "SymbolicUtilities.h"
/**
 * 
 */


int main(int argc, void** argv)
{
  try
    {
      Sundance::init(&argc, &argv);

      /*
        Create a mesh object. In this example, we will use a built-in method
        to create a uniform mesh on the unit line. In more realistic problems
        we would use a mesher to create a mesh, and then read the mesh using
        a MeshReader object. 
      */
      int n = 10;
      const double pi = 4.0*atan(1.0);
      MeshGenerator mesher = new LineMesher(0.0, pi, n);
      Mesh mesh = mesher.getMesh().getSubmesh();


      /* Define a symbolic object to represent the x coordinate function. */
      Expr x = new CoordExpr(0, "x");

      Expr alpha = new UnknownParameter();
      Expr alpha0 = new ParameterExpr(1.0);
      Expr PI = new ParameterExpr(pi, "pi");

      Expr target = x*(PI - x);
			
      Expr f = 0.5*Integral(pow( target - alpha*sin(x), 2.0));
      Expr df = Integral((target - alpha*sin(x))*sin(x));

      double fourier = (target*sin(x)).integral(mesh)/(sin(x)*sin(x)).integral(mesh);

      cerr << "fourier coeff = " << fourier << endl;

      for (double a=0.0; a<=3.0; a+=0.1)
        {
          alpha0.setParameterValue(a);
          cerr << "a,f,df = " << a << " " 
               << f.evaluateFunctional(mesh, alpha, alpha0) << " " 
               << df.evaluateFunctional(mesh, alpha, alpha0) << endl;
        }
    }
  catch(exception& e)
    {
      TSFOut::println(e.what());
      Testing::crash(__FILE__);
      Testing::timeStamp(__FILE__, __DATE__, __TIME__);
    }
  Sundance::finalize();
}

