13#include <boost/timer/timer.hpp>
27template<
class BarrierFunctional,
29 class ImageImpl=VectorImpl,
30 class QuadRule = TrapezoidalRule<typename BarrierFunctional::AnsatzVars::Grid::ctype, BarrierFunctional::AnsatzVars::Grid::dimension> >
35 typedef typename BarrierFunctional::AnsatzVars::Grid
Grid;
39 typedef typename BarrierFunctional::Scalar
Scalar;
41 typedef KaskadeLinearization<typename BarrierFunctional::OptimalityFunctional, VectorImpl>
Unconstrained;
42 typedef KaskadeLinearization<BarrierFunctional, VectorImpl, QuadRule>
Barrier;
43 typedef Dune::LinearOperator<DomainElement, ImageElement>
OperatorType;
46 : blin(fu,x_), vlin(fu.unconstrainedFunctional,x_), bfun(fu), prepared(false)
49 bfun.prepareConstraintsCache(vlin.getOriginImpl());
56 bfun.prepareConstraintsCache(vlin.getOriginImpl());
65 double getMu()
const {
return bfun.mu; }
67 int cols(
int cbegin,
int cend)
const {
return vlin.cols(cbegin, cend);}
68 int rows(
int cbegin,
int cend)
const {
return vlin.rows(cbegin, cend);}
70 void getMatrixBlocks(MatrixAsTriplet<Scalar>& mat,
int rbegin,
int rend,
int colbegin,
int colend)
const
75 bfun.prepareConstraintsCache(vlin.getOriginImpl());
78 vlin.getMatrixBlocks(mat, rbegin, rend, colbegin, colend);
79 blin.getMatrixBlocks(matb, rbegin, rend, colbegin, colend);
82 void getRHSBlocks(std::vector<Scalar>& rhs,
int rbegin,
int rend)
const
84 vlin.getRHSBlocks(rhs, rbegin, rend);
85 if(BarrierFunctional::parameterLin!=1)
89 bfun.prepareConstraintsCache(vlin.getOriginImpl());
92 blin.getRHSBlocks(rhsb, rbegin, rend);
93 int iend=
std::min(rhs.size(),rhsb.size());
94 if(BarrierFunctional::parameterLin==0)
for(
int i=0; i<iend;++i) rhs[i]+=rhsb[i];
95 if(BarrierFunctional::parameterLin==2)
for(
int i=0; i<iend;++i) rhs[i]=rhsb[i];
104 void flush() { vlin.flush(); blin.flush(); matb.resize(0); rhsb.resize(0); prepared=
false; }
106 void touch() { vlin.touch(); blin.touch(); }
112 bfun.prepareConstraintsCache(vlin.getOriginImpl());
115 return vlin.getValue()+blin.getValue();
122 bfun.prepareConstraintsCache(vlin.getOriginImpl());
125 return vlin.getL1norm()+blin.getL1norm();
132 mutable MatrixAsTriplet<Scalar> matb;
133 mutable std::vector<Scalar> rhsb;
136 BarrierFunctional
const& bfun;
137 mutable bool prepared;
143template<
class Descr,
class Functional,
class BarrierFu,
int paralin>
144 class LinearizationTraits<VariableSet<Descr>, IPFunctional<Functional,BarrierFu, paralin> >
146 typedef IPFunctional<Functional,BarrierFu, paralin> Func;
153template<
class BarrierFunction,
int yIdx>
157 template<
class Cache,
class Arg>
158 void computeRHS(Cache
const& cache,Arg
const& arg,
double const& trial)
160 r= cache.template d1<yIdx>(arg)+
H*trial;
166template<
class BarrierFunction,
int yIdx>
170 template<
class Cache,
class Arg>
171 void computeRHS(Cache
const& cache,Arg
const& arg,
double const& trial)
173 r=cache.d0()+
H*trial;
178#include "algorithm/opt_aux/src/include/zeroin.cpp"
181template<
template <
class BF,
int yIdx>
class PolyEquation>
185template<
class DomainElement,
class QuadraticModelBarrier,
class UnconstrainedLinearizationAt>
186void correct(DomainElement& tx,
const DomainElement& x, QuadraticModelBarrier
const& blin, UnconstrainedLinearizationAt
const& ulin,
double mu)
189 boost::timer::cpu_timer refTimer;
191 typedef typename UnconstrainedLinearizationAt::Functional Unconstrained;
192 typedef typename Unconstrained::AnsatzVars::Spaces Spaces;
193 typedef typename Unconstrained::Scalar Scalar;
195 int const yIdx = Unconstrained::yIdx;
196 int const ySIdx = boost::fusion::result_of::value_at_c<typename Unconstrained::AnsatzVars::Variables,yIdx>::type::spaceIndex;
198 typedef typename result_of::template value_at_c<typename DomainElement::Functions, yIdx>::type::Space YSpace;
199 int const dim = YSpace::dim;
200 YSpace
const& yspace(at_c<yIdx>(tx.data).space());
202 if(Unconstrained::ConstraintsCache::template bounds<yIdx>::upper==
false)
return;
204 typedef ShapeFunctionCache<typename YSpace::Grid,Scalar> SfCache;
206 typedef typename result_of::as_vector<typename result_of::transform<Spaces, GetEvaluators<SfCache> >::type>::type SFEvaluators;
207 SFEvaluators evaluators(transform(tx.descriptions.spaces,GetEvaluators<SfCache>(&sfCache)));
209 typename QuadraticModelBarrier::DomainCache bdomc(blin.template createDomainCache());
210 typename Unconstrained::ConstraintsCache uconc(ulin.getFunctional().createConstraintsCache(tx));
211 typename Unconstrained::DomainCache udomc(ulin.template createDomainCache(8));
213 typedef typename QuadraticModelBarrier::Linearization::Functional::BarrierFunction BarrierFunction;
215 VariationalArg<Scalar,dim> unitarg;
217 unitarg.gradient=0.0;
219 PolyEquation<BarrierFunction,yIdx> pe;
222 int nnodes(0),maxiter(0),sumiter(0);
224 std::vector<int> visited(yspace.degreesOfFreedom(),0);
226 std::cout <<
"PwD " << std::flush;
228 typedef typename YSpace::Grid::LeafGridView GridView;
230 typedef typename GridView::template Codim<0>::Iterator CellIterator;
232 for (CellIterator ci=yspace.gridView().template begin<0>(); ci!=yspace.gridView().template end<0>(); ++ci)
240 std::vector<Dune::FieldVector<typename YSpace::Grid::ctype, dim> >
const & iNodes(at_c<ySIdx>(evaluators).shapeFunctions().interpolationNodes());
242 for (
int i=0; i<iNodes.size(); ++i)
244 int globalIdx=at_c<ySIdx>(evaluators).globalIndices()[i];
245 if(!visited[globalIdx])
247 visited[globalIdx]++;
248 double trial = (*at_c<yIdx>(tx.data))[globalIdx][0];
249 double iterate = (*at_c<yIdx>( x.data))[globalIdx][0];
253 uconc.evaluateAt(iNodes[i],evaluators);
254 pe.upper = uconc.upperbound();
255 assert(iterate <= pe.upper);
260 udomc.evaluateAt(iNodes[i],evaluators);
261 bdomc.evaluateAt(iNodes[i],evaluators);
268 pe.H = udomc.template d2<yIdx,yIdx,dim>(unitarg,unitarg)[0][0];
269 pe.computeRHS(bdomc,unitarg,trial);
272 double upperB =
std::min(trial,pe.upper);
273 double lowerB = (upperB+iterate)/2.0;
277 double solution = zeroin(lowerB,upperB,pe,(upperB-lowerB)*1e-12+4*std::numeric_limits<Scalar>::epsilon()*(1+upperB),iterations,100);
279 (*at_c<yIdx>(tx.data))[globalIdx][0] = solution;
283 maxiter =
std::max(maxiter,iterations);
284 sumiter += iterations;
285 ratio=
std::min(ratio,std::fabs((solution-iterate)/(trial-iterate)));
307 std::cout << (double)(refTimer.elapsed().user)/1e9 <<
" sec.";
308 std::cout <<
"MaxRatio: " << ratio << std::endl;
312template<
class Functional,
class DomainElement,
class Implementation=Br
idge::IPLinearization<Functional, DomainElement> >
315 typedef typename Functional::OptimalityFunctional Unconstrained;
316 typedef Functional Combined;
324 void addPerturbation(AbstractFunctionSpaceElement & trialIterate,
325 AbstractFunctionSpaceElement
const& correction,
326 AbstractLinearization
const& lin,
327 std::vector<AbstractFunctionSpaceElement* > basis = std::vector<AbstractFunctionSpaceElement* >())
const
329 trialIterate = lin.getOrigin();
332 trialIterate += correction;
334 for(
int i=0; i<trialIterate.nComponents();++i)
335 if(trialIterate.getRole(i)!=
"dual")
336 trialIterate.axpy(1.0,correction,i);
339 DomainElement
const& x=Bridge::getImpl<DomainElement>(lin.getOrigin());
340 DomainElement& tx=Bridge::getImpl<DomainElement>(trialIterate);
343 Bridge::Linearization<Implementation>
const& limpl(
dynamic_cast<Bridge::Linearization<Implementation> const&
>(lin));
344 double mu = limpl.getLinImpl().getMu();
346 LinearizationAt<Unconstrained> ulin(limpl.getLinImpl().getUnconstrained().getLinImpl().getFunctional(),tx);
347 QuadraticModel<LinearizationAt<Combined>,
false> blin(linearization(limpl.getLinImpl().getBarrier().getLinImpl().getFunctional(),x),
348 Bridge::getImpl<DomainElement>(correction));
351 pc.
correct(tx, x, blin, ulin, mu);
358template<
class DomainElement,
class QBarrierModel,
class ParameterModel,
class LModel>
359void corrTangent(DomainElement& tx,
const DomainElement& x, QBarrierModel
const& blin, ParameterModel
const& plin, LModel
const& ulin,
double muLast,
double mu)
363 typedef typename LModel::Functional Unconstrained;
364 typedef typename LModel::AnsatzVars::Spaces Spaces;
365 typedef typename LModel::AnsatzVars::IndexSet IndexSet;
366 typedef typename Unconstrained::Entity Entity;
367 typedef typename LModel::Scalar Scalar;
368 int const yIdx = Unconstrained::yIdx;
369 typedef typename result_of::template value_at_c<typename DomainElement::Functions, yIdx>::type::Space YSpace;
370 int const dim = YSpace::dim;
372 double deltaMu = muLast-mu;
374 if(Unconstrained::ConstraintsCache::template bounds<yIdx>::upper==0)
return;
376 YSpace
const& yspace(at_c<yIdx>(tx.data).space());
377 typename YSpace::Evaluator ysfs(yspace);
379 typedef ShapeFunctionCache<typename YSpace::Grid,Scalar> SfCache;
382 typedef typename result_of::as_vector<typename result_of::transform<Spaces, GetEvaluators<SfCache> >::type>::type
Evaluators;
383 Evaluators evaluators(transform(tx.descriptions.spaces,GetEvaluators<SfCache>(&sfCache)));
385 typename QBarrierModel::DomainCache bdc(blin.template createDomainCache());
386 typename ParameterModel::DomainCache pdc(plin.template createDomainCache());
387 typename Unconstrained::ConstraintsCache udc(ulin.getFunctional().createConstraintsCache(tx));
389 VariationalArg<Scalar,dim> unitarg;
390 unitarg.value[0]=1.0;
391 for(
int i=0; i < dim; ++i) unitarg.gradient[0][i]=0.0;
393 typedef typename IndexSet::template Codim<0>::template Partition<Dune::All_Partition>::Iterator CellIterator;
394 for (CellIterator ci=yspace.indexSet().template begin<0,Dune::All_Partition>();
395 ci!=yspace.indexSet().template end<0,Dune::All_Partition>(); ++ci)
402 std::vector<Dune::FieldVector<typename YSpace::Grid::ctype, dim> >
const & iNodes(ysfs.shapeFunctions().interpolationNodes());
404 for (
int i=0; i<iNodes.size(); ++i)
406 ysfs.evaluateAt(iNodes[i]);
408 udc.evaluateAt(iNodes[i],evaluators);
409 bdc.evaluateAt(iNodes[i],evaluators);
410 pdc.evaluateAt(iNodes[i],evaluators);
411 pe.aqp = udc.quadTermA();
412 pe.aq=(bdc.template d1<yIdx,dim>(unitarg))[0]+deltaMu*(pdc.template d1<yIdx,dim>(unitarg))[0]+udc.quadTermB();
415 double trial= -(*at_c<yIdx>(tx.data))[ysfs.globalIndices()[i]][0]+udc.upperbound();
416 double iterate= -(*at_c<yIdx>(x.data))[ysfs.globalIndices()[i]][0]+udc.upperbound();
417 double upper =
std::max(trial,iterate);
418 double lower =
std::min(trial,iterate);
420 yc2=
bisection(
std::max(0.0,lower),upper,pe,upper*1e-6+4*std::numeric_limits<Scalar>::epsilon()*(1+upper),iterations);
421 (*at_c<yIdx>(tx.data))[ysfs.globalIndices()[i]][0]= udc.upperbound()-yc2;
440template<
class IPF,
class DomainVector>
443 typedef typename IPF::OptimalityFunctional Unconstrained;
449 AbstractLinearSolver& solver_, AbstractNorm
const* normPlain_=0,
450 NewtonsMethod* finalsolver_=0) :
451 HomotopyBase(n_, p_),
455 normPlain(normPlain_),
456 finalsolver(finalsolver_)
458 if(!normPlain_) normPlain=&norm;
459 if(!finalsolver_) finalsolver=&n_;
463 iterate=trialIterate->clone();
464 predictor=trialIterate->clone();
465 tangent=trialIterate->clone();
466 ptangent=trialIterate->clone();
473 double b = pp.omega*pp.accuracyCorrector;
474 double c = pp.eta*pp.omega*p.mu;
475 double a = c+p.desiredContraction;
476 double sigma = (b+sqrt(b*b+4*a*c))/(2*a);
481 f.
err = pp.accuracyCorrector;
485 f.
Theta = p.desiredContraction;
489 double sig =
bisection(1e-20,1.0-1e-15,f,1e-6,iter);
491 sigma =
std::min(sigma,p.reductionFactorWorst);
492 sigma =
std::max(sigma,p.reductionFactorBest);
493 if(step==2) sigma=p.reductionStart;
499 p.sigma=0.5+p.sigma/2.0;
503 virtual double muFinal() {
return p.muFinal;};
507 *predictor -= *trialIterate;
508 double n(norm(*predictor));
510 std::unique_ptr<AbstractFunctional> fuPtr(functional->getParameterLinFunctional(
makePars(p.muTrial.value())));
511 std::unique_ptr<AbstractLinearization> paraLinearization(fuPtr->getLinearization(*trialIterate));
512 solver.solve(*tangent,*paraLinearization);
513 double nD=norm(*tangent);
514 double nDp=norm(*ptangent);
518 *ptangent -= *tangent;
519 std::cout <<
"Difference in Tangent vectors:" << norm(*ptangent)/
std::max(nD,nDp) << std::endl;
522 std::unique_ptr<AbstractFunctional> fuVPtr(functional->getLinFunctionValue(
makePars(p.muTrial.value())));
523 std::unique_ptr<AbstractLinearization> paraLinFu(fuVPtr->getLinearization(*trialIterate));
524 paraLinFu->evald(*iterate);
525 double slopeJ = iterate->applyAsDualTo(*tangent);
526 pp.jpl=p.mu.value()*slopeJ;
527 double nDP=(*normPlain)(*tangent);
528 *ptangent -= *tangent;
529 double nDiff=norm(*ptangent);
532 pp.curvature=nDiff/p.deltaMu;
534 GuardedCovariantNewtonParameters
const& cnp(
dynamic_cast<GuardedCovariantNewtonParameters const&
>(corrector.getParameters()));
535 pp.omega=cnp.omega0.value();
536 pp.accuracyCorrector=cnp.accuracyReached;
537 std::cout <<
"Norm:" << n/p.deltaMu <<
" ||x'||_2:" << nDP <<
" Dmu:" << p.deltaMu <<
" ||x'||_x:"<< pp.eta <<
" omega:" << pp.omega << std::endl;
543 if(p.mu==p.muTrial)
return;
546 std::unique_ptr<AbstractFunctional> fuPtr(functional->getParameterLinFunctional(
makePars(p.muTrial.value())));
547 std::unique_ptr<AbstractLinearization> paraLinearization(fuPtr->getLinearization(*trialIterate));
548 solver.solve(*tangent,*paraLinearization);
551 predictor->axpy(p.mu-p.muTrial,*tangent);
552 DomainVector& tx=Bridge::getImpl<DomainVector>(*iterate);
553 DomainVector& px=Bridge::getImpl<DomainVector>(*predictor);
554 DomainVector
const& cx=Bridge::getImpl<DomainVector>(*tangent);
555 std::unique_ptr<AbstractFunctional> fuPtr(functional->getFunctional(
makePars(p.mu.value())));
556 std::unique_ptr<AbstractLinearization> linPtr(fuPtr->getLinearization(*iterate));
557 std::unique_ptr<AbstractLinearization> paraLinearization(fuPtr->getLinearization(*iterate));
559 Bridge::Linearization<Implementation>
const& limpl(
dynamic_cast<Bridge::Linearization<Implementation> const&
>(*linPtr));
560 Bridge::Linearization<Implementation>
const& plimpl(
dynamic_cast<Bridge::Linearization<Implementation> const&
>(*paraLinearization));
562 LinearizationAt<Barrier> blin(limpl.getLinImpl().getBarrier().getLinImpl().getFunctional(),tx);
563 LinearizationAt<Barrier> plin(plimpl.getLinImpl().getBarrier().getLinImpl().getFunctional(),tx);
564 LinearizationAt<Unconstrained> ulin(limpl.getLinImpl().getUnconstrained().getLinImpl().getFunctional(),tx);
566 corrTangent(px, tx, blin, plin, ulin, p.muTrial, p.mu);
567 for (
int i=0; i<temp.size(); ++i)
568 if((*boost::fusion::at_c<Barrier::yIdx>(cx.data))[i][0] < 0) (*boost::fusion::at_c<Barrier::yIdx>(px.data))[i][0] = temp[i];
569 *trialIterate=*predictor;
570 *predictor-=*iterate;
571 std::unique_ptr<AbstractFunctional> fuPtr2(functional->getParameterLinFunctional(
makePars(p.muTrial.value())));
572 std::unique_ptr<AbstractLinearization> paraLinearization2(fuPtr2->getLinearization(*trialIterate));
573 solver.solve(*ptangent,*paraLinearization2);
579 if(p.muTrial < p.muFinal) corrector.setDesiredAccuracy(p.accfinal);
582 if(pp.eta.isValid()) corrector.setDesiredAccuracy(1000000*
std::max(p.accfinal*0.25,
lengthOfPath()*p.relDistanceToPath));
583 else corrector.setDesiredAccuracy(sqrt(p.muTrial)*p.relDistanceToPath);
584 corrector.setDesiredRelativeAccuracy(p.relDistanceToPath);
587 virtual void finalizeCorrector() { nNewton += corrector.stepsPerformed(); pp.newtonSum=nNewton;};
591 std::cout <<
"----------------------- Final Correction Step ---------------------" << std::endl;
592 finalsolver->resetParameters();
593 finalsolver->setDesiredAccuracy(p.accfinal);
594 finalsolver->setDesiredRelativeAccuracy(1.0);
595 std::unique_ptr<AbstractFunctional> fuPtr(functional->getFunctional(
makePars(p.muTrial.value())));
596 std::cout <<
"muTrial: " << p.muTrial << std::endl;
597 finalsolver->reportOnIteration(
true);
598 finalsolver->solve(fuPtr.get(), *trialIterate);
599 p.correctorTermination=corrector.getParameters().termination;
603 *iterate=*trialIterate;
604 p.j=functional->getFunctional(
makePars(p.muTrial.value()))->getLinearization(*iterate)->eval();
605 jModelL.update(p.muTrial,p.j);
607 p.jp=jModelL.getValue(p.muTrial);
608 std::cout <<
"Est. Error in Functional:" << p.jp << std::endl;
609 pp.timemeasured=overalltime.elapsed();
618 return 2*p.mu*pp.slope;
625 HomotopyBase::logQuantities();
632 std::ofstream eout(
"eta.log"); pp.eta.print(eout);
633 std::ofstream epout(
"slope.log"); pp.slope.print(epout);
634 std::ofstream cpout(
"curvature.log"); pp.curvature.print(cpout);
635 std::ofstream nout(
"newtonSum.log"); pp.newtonSum.print(nout);
636 std::ofstream oout(
"omega.log"); pp.omega.print(oout);
637 std::ofstream sout(
"sigma.log"); p.sigma.print(sout);
638 std::ofstream outmu(
"mu.log"); p.muTrial.print(outmu);
639 std::ofstream outj(
"j.log"); p.j.print(outj);
640 std::ofstream outjp(
"jp.log"); p.jp.print(outjp);
641 std::ofstream outjpl(
"jplin.log"); pp.jpl.print(outjpl);
642 std::ofstream outac(
"ac.log"); pp.accuracyCorrector.print(outac);
643 std::ofstream outtm(
"time.log"); pp.timemeasured.print(outtm);
647 std::unique_ptr<AbstractFunctionSpaceElement> iterate, predictor, tangent, ptangent;
649 AbstractNorm
const& norm;
650 AbstractLinearSolver& solver;
651 InteriorPointParametersSqrt pp;
654 AbstractNorm
const* normPlain;
655 NewtonsMethod* finalsolver;
657 boost::timer::cpu_timer overalltime;
Linearization for Constrained Optimization with Barrier methods.
BarrierFunctional IPFunctional
BarrierFunctional::AnsatzVars::Grid Grid
DomainElement const & getOriginImpl() const
int rows(int cbegin, int cend) const
double getMu() const
Return gap parameter.
IPLinearization(BarrierFunctional const &fu, DomainElement const &x_)
int cols(int cbegin, int cend) const
BarrierFunctional::Scalar Scalar
Unconstrained const & getUnconstrained() const
Barrier const & getBarrier() const
Dune::LinearOperator< DomainElement, ImageElement > OperatorType
Grid::LeafGridView GridView
KaskadeLinearization< typename BarrierFunctional::OptimalityFunctional, VectorImpl > Unconstrained
void getRHSBlocks(std::vector< Scalar > &rhs, int rbegin, int rend) const
KaskadeLinearization< BarrierFunctional, VectorImpl, QuadRule > Barrier
void getMatrixBlocks(MatrixAsTriplet< Scalar > &mat, int rbegin, int rend, int colbegin, int colend) const
IPLinearization< Func, typename Func::AnsatzVars::VariableSet > Linearization
virtual void finalizeCorrector()
virtual void updateIterate()
virtual void finalizeHomotopy()
virtual void updateModelOfHomotopy()
virtual void initialize()
virtual void recoverIterate()
virtual void logQuantities()
virtual void computePredictor(int step)
InteriorPointTangentialPredictor(NewtonsMethod &n_, AbstractNorm const &norm_, InteriorPointParameters &p_, AbstractLinearSolver &solver_, AbstractNorm const *normPlain_=0, NewtonsMethod *finalsolver_=0)
virtual double muOnSuccess(int step)
virtual void initializeCorrector()
virtual double muOnFailure()
virtual double lengthOfPath()
PWDampingChart(bool includeDuals_=true)
Pointwise damping strategy.
void correct(DomainElement &tx, const DomainElement &x, QuadraticModelBarrier const &blin, UnconstrainedLinearizationAt const &ulin, double mu)
Utility classes for the definition and use of variational functionals.
Parameters< ParameterType > makePars(ParameterType const &p)
void moveEvaluatorsToIntegrationPoint(Evaluators &evals, Dune::FieldVector< CoordType, dim > const &x, Dune::QuadratureRule< CoordType, subDim > const &qr, int ip, int subId)
Moves all provided evaluators to the given integration point, evaluating the shape functions there.
typename boost::fusion::result_of::as_vector< typename boost::fusion::result_of::transform< Spaces, GetEvaluatorTypes >::type >::type Evaluators
the heterogeneous sequence type of Evaluators for the given spaces
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
void corrTangent(DomainElement &tx, const DomainElement &x, QBarrierModel const &blin, ParameterModel const &plin, LModel const &ulin, double muLast, double mu)
Pointwise damping strategy.
Functional for Barrier/Interior Point methods.
double bisection(double a, double b, Equation const &f, double accuracy, int &iterations)
Performs bisection algorithm to find a zero of a.
void moveEvaluatorsToCell(Evaluators &evals, Cell const &cell)
Moves all provided evaluators to the given cell.
double operator()(double y) const
void computeRHS(Cache const &cache, Arg const &arg, double const &trial)
void computeRHS(Cache const &cache, Arg const &arg, double const &trial)
double operator()(double y) const
double operator()(double sigma) const
Variables and their descriptions.