Expr ListExpr::join(const Expr& other) const 
{
  Expr rtn = new ListExpr(elements_);
  
  for (int i=0; i<other.size(); i++)
    {
      rtn.append(other[i]);
    }

  return rtn;
}
void L2Projector::init(const DiscreteSpace& space,
                       const CoordinateSystem& coordSys,
                       const Expr& expr,
                       const LinearSolver<double>& solver)
{
    TEST_FOR_EXCEPTION(space.basis().size() != expr.size(),
                       RuntimeError,
                       "mismatched vector structure between basis and expr");

    TEST_FOR_EXCEPTION(space.basis().size() == 0,
                       RuntimeError,
                       "Empty basis?");

    Expr v = new TestFunction(space.basis()[0], "dummy_v[0]");
    Expr u = new UnknownFunction(space.basis()[0], "dummy_u[0]");

    for (int i=1; i<space.basis().size(); i++)
    {
        v.append(new TestFunction(space.basis()[i], "dummy_v["
                                  + Teuchos::toString(i)+"]"));
        u.append(new UnknownFunction(space.basis()[i], "dummy_u["
                                     + Teuchos::toString(i)+"]"));
    }

    CellFilter interior = new MaximalCellFilter();

    Expr eqn = 0.0;
    Expr J = coordSys.jacobian();

    for (int i=0; i<space.basis().size(); i++)
    {
        eqn = eqn + Integral(space.cellFilters(i),
                             J*v[i]*(u[i]-expr[i]),
                             new GaussianQuadrature(4));
    }
    Expr bc;

    prob_ = LinearProblem(space.mesh(), eqn, bc, v, u, space.vecType());
    solver_ = solver;
}
Expr ListExpr::flatten() const 
{
  Expr rtn = new ListExpr();

  for (int i=0; i<this->size(); i++)
    {
      Expr e = element(i).flatten();
      for (int j=0; j<e.size(); j++)
        {
          rtn.append(e[j]);
        }
    }

  return rtn;
}