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(); }
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"); }