← Back to team overview

dolfin team mailing list archive

Re: [Branch ~dolfin-core/dolfin/main] Rev 5463: Change VariationalProblem interface.

 

On Wed, Jan 05, 2011 at 08:06:58PM +0000, Garth N. Wells wrote:
>
>
> On 05/01/11 20:04, Anders Logg wrote:
> >On Wed, Jan 05, 2011 at 07:50:33PM +0000, Garth N. Wells wrote:
> >>
> >>
> >>On 05/01/11 19:37, Anders Logg wrote:
> >>>On Wed, Jan 05, 2011 at 07:16:45PM +0000, Garth N. Wells wrote:
> >>>>
> >>>>
> >>>>On 05/01/11 18:52, Marie E. Rognes wrote:
> >>>>>
> >>>>>
> >>>>>On 5. jan. 2011, at 19:30, Anders Logg<logg@xxxxxxxxx>    wrote:
> >>>>>
> >>>>>>On Wed, Jan 05, 2011 at 05:21:07PM +0000, Garth N. Wells wrote:
> >>>>>>>
> >>>>>>>
> >>>>>>>On 05/01/11 15:12, Anders Logg wrote:
> >>>>>>>>On Wed, Jan 05, 2011 at 03:51:32PM +0100, Marie E. Rognes wrote:
> >>>>>>>>>On 01/05/2011 03:32 PM, Garth N. Wells wrote:
> >>>>>>>>>
> >>>>>>>>>    I wonder if the distinction now between linear and nonlinear problems is
> >>>>>>>>>    too subtle? Another way would be to have classes
> >>>>>>>>>
> >>>>>>>>>      LinearVariationalProblem
> >>>>>>>>>
> >>>>>>>>>    and
> >>>>>>>>>
> >>>>>>>>>      NonlinearVariationalProblem
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>I agree that the distinction in the interface can be called subtle (or
> >>>>>>>>>alternatively, "almost seamless"). But, I think I prefer keeping the input
> >>>>>>>>>minimal and rather giving more verbose feedback ("starting linear/nonlinear
> >>>>>>>>>solve", throwing errors if input is inconsistent etc) than increasing the
> >>>>>>>>>verbosity of the required input.
> >>>>>>>>>
> >>>>>>>>>Also cf. thread "VariationalProblem interface(s)" from Oct 20th for more
> >>>>>>>>>motivation behind this change.
> >>>>>>>>
> >>>>>>>>I tend to prefer overloading and like the shorter "VariationalProblem"
> >>>>>>>>for both linear and nonlinear problems.
> >>>>>>>>
> >>>>>>>>The rationale is that the most important argument is placed first:
> >>>>>>>>
> >>>>>>>>  F, F'
> >>>>>>>>  a, L
> >>>>>>>>
> >>>>>>>
> >>>>>>>My first issue is that it's not easy to read. Scanning through a
> >>>>>>>function, it's not immediately obvious that a problem is linear or
> >>>>>>>nonlinear.
> >>>>>>>
> >>>>>>>Another reason to separate linear and nonlinear clases is that there
> >>>>>>>is almost no shared code (none?) in VariationalProblem.cpp, so it
> >>>>>>>doesn't make much sense to roll linear and nonlinear cases into one
> >>>>>>>class. The other point is that they will share few parameters - I
> >>>>>>>would like eventually to have more options for how a nonlinear
> >>>>>>>problem is solved.
> >>>>>
> >>>>>
> >>>>>Good point -- there are a lot of linear vs nonlinear checks in the current VP.cpp...
> >>>>>
> >>>>>
> >>>>>>>
> >>>>>>>Garth
> >>>>>>
> >>>>>>We have a blueprint on this. The solvers should be split into
> >>>>>>FooSolver classes anyway so the sharing of code is not much of an
> >>>>>>issue.
> >>>>
> >>>>A linear solver is only one ingredient in a nonlinear solver. There
> >>>>is also modified Newton, quasi-Newton, path following,
> >>>>Newton-Krylov, preconditioner re-use, . . . .
> >>>
> >>>I don't understand this point. That would all be part of
> >>>NonlinearVariationalSolver.
> >>>
> >>
> >>I'm not sure that we would want a NonlinearVariationalSolver class.
> >>It should be more abstract and just be a NonlinearSolver.
> >
> >Where would be then implement the algorithm for solving a nonlinear
> >variational problem? It should not be in NonlinearVariationalProblem
> >as that goes against the design for all other algorithms in DOLFIN
> >(which are implemented in separate classes).
> >
> >Perhaps there's also use for an abstract NonlinearSolver, but we also
> >need a concrete implementation of a solver for nonlinear variational
> >problems and then it would be natural to call it NonlinearVariationalSolver.
> >
> >>>>>This way of solving the above issue makes very much sense to me.
> >>>>>
> >>>>>
> >>>>>>The solvers can go in
> >>>>>>
> >>>>>>  static LinearVariationalSolver::solve() const
> >>>>>>  static NonlinearVariationalSolver::solve() const
> >>>>>>
> >>>>>>Then it's a matter of taste whether we have VariationalProblem or
> >>>>>>two separate classes. I prefer one class since
> >>>>>>
> >>>>>>1. I like overloading in general
> >>>>>>
> >>>>>>2. It's a shorter name
> >>>>>>
> >>>>>>3. It's (mostly) backwards compatible
> >>>>>>
> >>>>>
> >>>>
> >>>>We could merge a lot of classes that don't share code into one
> >>>>class, and distinguish cases through the constructor arguments, but
> >>>>that would be a bad design. If they don't share code, they shouldn't
> >>>>be in the same class.
> >>>
> >>>They would essentially be in two different classes (the two different
> >>>solver classes). The VariationalProblem class would just be a simple
> >>>data structure for packing up the data defining a variational problem.
> >>>
> >>>Note that the design for solving variational problems is different
> >>>from what we use in other places like linear systems. There we only
> >>>have solver classes and the input is a Matrix and a Vector.
> >>>
> >>>We could do the same thing for variational problems:
> >>>
> >>>   u = solver.solve(F, bcs)
> >>>   u = solve(F, bcs)
> >>>
> >>>>I would like to have LinearVariationalProblem and
> >>>>NonlinearVariationalProblem, and I'm pretty strongly opposed to
> >>>>artificially forcing both into once class if there is no/minimal
> >>>>code sharing. A compromise design could be:
> >>>>
> >>>>   class LinearVariationalProblem : GenericVariationalProbem
> >>>>   class NonlinearVariationalProblem : GenericVariationalProbem
> >>>>
> >>>>and for simple usage cases
> >>>>
> >>>>   class VariationalProblem
> >>>>   {
> >>>>   public:
> >>>>
> >>>>     // constructors
> >>>>    VariationalProblem( .... )
> >>>>    { variational_problem = new LinearVariationalProblem; }
> >>>>
> >>>>    VariationalProblem( .... )
> >>>>    { variational_problem = new NonlinearVariationalProblem; }
> >>>>
> >>>>    void solve(Function&   u)
> >>>>    { variational_problem->solve(u); }
> >>>>
> >>>>   private:
> >>>>
> >>>>     GenericVariationalProblem* variational_problem ;
> >>>>
> >>>>   }
> >>>
> >>>The essential bits should go into *solver* classes (which should be
> >>>separate), like we do for everything else.
> >>>
> >>>Then VariationalProblem is just a collection of ca 3 objects (two
> >>>forms, a list of bcs + maybe something else). At that point, it's just
> >>>a matter of taste whether we should have two such classes (with long
> >>>names) or if we can reuse one very simple container for both cases.
> >>>
> >>
> >>OK. If VariationalProblem is just a light-weight collection (unlike
> >>what it is now), then my design objections fall away. I'm still
> >>concerned that the distinction between linear and nonlinear problems
> >>is too subtle and thus error prone (I would have no difficulty on
> >>the Python side using named arguments, e.g. pde =
> >>VariationalProblem(F=..., J=...,...)).
> >
> >I think the J will be optional, at least on the Python side so we will
> >have
> >
> >   VariationalProblem(a, L, bcs) -->  linear
> >   VariationalProblem(F, bcs)    -->  nonlinear, J computed automatically
> >
> >Then it would be very clear which is linear and which is nonlinear.
> >
>
> The Jacobian cannot always be computed automatically, e.g.
> plasticity problems. It is also desirable in some case to not use
> the exact J.

Yes, but in those cases one can use the optional argument J=something.

--
Anders



References