void LinearPDEConstrainedObj::solveState(const Vector<double>& x) const
{
  Tabs tab(0);
  PLAYA_MSG2(verb(), tab << "solving state"); 
  PLAYA_MSG3(verb(), tab << "|x|=" << x.norm2()); 
  PLAYA_MSG5(verb(), tab << "x=" << endl << tab << x.norm2());
  setDiscreteFunctionVector(designVarVal(), x);

  /* solve the state equations in order */
  for (int i=0; i<stateProbs_.size(); i++)
  {
    SolverState<double> status 
      = stateProbs_[i].solve(solvers_[i], stateVarVals(i));
    TEUCHOS_TEST_FOR_EXCEPTION(status.finalState() != SolveConverged,
      std::runtime_error,
      "state equation could not be solved: status="
      << status.stateDescription());
  }

  PLAYA_MSG2(verb(), tab << "done state solve"); 
  /* do postprocessing */
  statePostprocCallback();
}
Ejemplo n.º 2
0
  SolverState<double> PCGSolver::solveUnprec(const LinearOperator<double>& A,
					     const Vector<double>& b,
					     Vector<double>& x) const
  {
    Tabs tab0;
    const ParameterList& params = parameters();
    int verb = 0;
    if (params.isParameter("Verbosity"))
      {
	verb = getParameter<int>(params, "Verbosity");
      }

    int maxIters = getParameter<int>(params, "Max Iterations");
    double tol = getParameter<double>(params, "Tolerance");

    /* Display diagnostic information if needed */
    PLAYA_ROOT_MSG1(verb, tab0 << "Playa CG Solver");
    Tabs tab1;
    PLAYA_ROOT_MSG2(verb, tab0);
    PLAYA_ROOT_MSG2(verb, tab1 << "Verbosity      " << verb);
    PLAYA_ROOT_MSG2(verb, tab1 << "Max Iters      " << maxIters);
    PLAYA_ROOT_MSG2(verb, tab1 << "Tolerance      " << tol);

    /* if the solution vector isn't initialized, set to RHS */
    if (x.ptr().get()==0) x = b.copy();
    
    Vector<double> r = b - A*x;
    Vector<double> p = r.copy();
    double bNorm = b.norm2();
    PLAYA_ROOT_MSG2(verb, tab1 << "Problem size:  " << b.space().dim());
    PLAYA_ROOT_MSG2(verb, tab1 << "||rhs||        " << bNorm);

    /* Prepare the status object to be returned */
    SolverState<double> rtn;
    bool converged = false;
    bool shortcut = false;

    /* Check for zero rhs */
    if (bNorm==0.0)
      {
	PLAYA_ROOT_MSG2(verb, tab1 << "RHS is zero!");
	rtn = SolverState<double>(SolveConverged, "Woo-hoo! Zero RHS shortcut", 
				  0, 0.0);
	shortcut = true;
      }

    double rNorm = 0.0;
    double rtr = r*r;

    if (!shortcut)
      {
	PLAYA_ROOT_MSG2(verb, tab1 << endl << tab1 << "CG Loop");

	for (int k=0; k<maxIters; k++)
	  {
	    Tabs tab2;
	    Vector<double> Ap = A*p;
	    double alpha = rtr/(p*Ap);
	    x += alpha*p;
	    r -= alpha*Ap;
	    double rtrNew = r*r;
	    rNorm = sqrt(rtrNew);
	    PLAYA_ROOT_MSG2(verb, tab2 << "iter=" << setw(10) 
			    << k << setw(20) << "||r||=" << rNorm);
	    /* check relative residual */
	    if (rNorm < bNorm*tol) 
	      {
		rtn = SolverState<double>(SolveConverged, "Woo-hoo!", 
					  k, rNorm);
		converged = true;
		break;
	      }
	    double beta = rtrNew/rtr;
	    rtr = rtrNew;
	    p = r + beta*p;
	  }
      }

    if (!converged && !shortcut)
      {
	rtn = SolverState<double>(SolveFailedToConverge, 
				  "CG failed to converge", 
				  maxIters, rNorm);
      }

    PLAYA_ROOT_MSG2(verb, tab0 << endl
		    << tab0 << "CG finished with status " 
		    << rtn.stateDescription());
    return rtn;
  }
void LinearPDEConstrainedObj
::solveStateAndAdjoint(const Vector<double>& x) const
{
  Tabs tab(0);
  PLAYA_MSG2(verb(), tab << "solving state and adjoint"); 
  PLAYA_MSG3(verb(), tab << "|x|=" << x.norm2()); 
  PLAYA_MSG5(verb(), tab << "x=" << endl << tab << x.norm2()); 

  Tabs tab1;
  setDiscreteFunctionVector(designVarVal(), x);

  PLAYA_MSG3(verb(), tab1 << "solving state eqns");
  /* solve the state equations in order */
  for (int i=0; i<stateProbs_.size(); i++)
  {
    SolverState<double> status 
      = stateProbs_[i].solve(solvers_[i], stateVarVals(i));

    /* if the solve failed, write out the design var and known state
     * variables */
    if (status.finalState() != SolveConverged)
    {
      FieldWriter w = new VTKWriter("badSolve");
      w.addMesh(Lagrangian().mesh());
      w.addField("designVar", new ExprFieldWrapper(designVarVal()));
      for (int j=0; j<i; j++)
      {
        Expr tmp = stateVarVals(j).flatten();
        for (int k=0; k<tmp.size(); k++)
        {
          w.addField("stateVar-"+Teuchos::toString(j)+"-"+Teuchos::toString(k),
            new ExprFieldWrapper(tmp[k]));
        }
      }
      w.write();
    }
    TEUCHOS_TEST_FOR_EXCEPTION(status.finalState() != SolveConverged,
      std::runtime_error,
      "state equation " << i 
      << " could not be solved: status="
      << status.stateDescription());
  }

  PLAYA_MSG3(verb(), tab1 << "done solving state eqns");

  /* do postprocessing */
  statePostprocCallback();

  PLAYA_MSG3(verb(), tab1 << "solving adjoint eqns");

  /* solve the adjoint equations in reverse order */
  for (int i=adjointProbs_.size()-1; i>=0; i--)
  {
    SolverState<double> status 
      = adjointProbs_[i].solve(solvers_[i], adjointVarVals(i));

    /* if the solve failed, write out the design var and known state
     * and adjoint variables */
    if (status.finalState() != SolveConverged)
    {
      FieldWriter w = new VTKWriter("badSolve");
      w.addMesh(Lagrangian().mesh());
      w.addField("designVar", new ExprFieldWrapper(designVarVal()));
      for (int j=0; j<stateProbs_.size(); j++)
      {
        Expr tmp = stateVarVals(j).flatten();
        for (int k=0; k<tmp.size(); k++)
        {
          w.addField("stateVar-"+Teuchos::toString(j)+"-"+Teuchos::toString(k),
            new ExprFieldWrapper(tmp[k]));
        }
      }
      for (int j=adjointProbs_.size()-1; j>i; j--)
      {
        Expr tmp = adjointVarVals(j).flatten();
        for (int k=0; k<tmp.size(); k++)
        {
          w.addField("adjointVar-"+Teuchos::toString(j)+"-"+Teuchos::toString(k),
            new ExprFieldWrapper(tmp[k]));
        }

      }
      w.write();

    }
    TEUCHOS_TEST_FOR_EXCEPTION(status.finalState() != SolveConverged,
      std::runtime_error,
      "adjoint equation " << i 
      << " could not be solved: status="
      << status.stateDescription());
  }
  PLAYA_MSG3(verb(), tab1 << "done solving adjoint eqns");
  PLAYA_MSG2(verb(), tab1 << "done solving state and adjoint eqns");
}