Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IDAInterface #4852

Merged
merged 10 commits into from Sep 16, 2017
Merged

IDAInterface #4852

merged 10 commits into from Sep 16, 2017

Conversation

luca-heltai
Copy link
Member

@luca-heltai luca-heltai commented Aug 15, 2017

@luca-heltai
Copy link
Member Author

@jdannberg here it is. :)

@jdannberg
Copy link
Contributor

Great, thanks!

* scalar \f$\alpha\f$ changes whenever the step size or method order
* changes.
*/
template<typename VEC=Vector<double> >
Copy link
Contributor

@davydden davydden Aug 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Elsewhere we call template VectorType

#ifdef DEAL_II_WITH_MPI

#ifdef DEAL_II_WITH_TRILINOS
void copy(TrilinosWrappers::MPI::Vector &dst, const N_Vector &src);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and below are not documented

*/
IDAInterface(const std::string name="",
const MPI_Comm mpi_comm = MPI_COMM_WORLD);
/** House cleaning. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space before and indentation the same way as constructor

/** House cleaning. */
~IDAInterface();

/** Declare parameters for this class to function properly. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what u mean by "to function properly"? Can u please reprhrase?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking at the test, i would list here explicitly all the parameters which will be declared. Otherwise users are forced to dig into the source code to see what is actually happening inside to be able to use this function.
I would take the output of ParameterHandler::print_parameters().

const unsigned int step_number)> output_step;

/**
* Evaluate wether the solver should be restarted (for example because the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whether

*/
void set_functions_to_trigger_an_assert();

/** Initial time for the DAE.*/
Copy link
Contributor

@davydden davydden Aug 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could u please indent it the way we do elsewhere, i.e.

/**
 * Initial time for the DAE.
 */

Same below.

N_Vector diff_id;

#ifdef DEAL_II_WITH_MPI
MPI_Comm communicator;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation

/** Output stream */
ConditionalOStream pcout;

unsigned int system_size;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docu


unsigned int system_size;

unsigned int local_system_size;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docu

@bangerth
Copy link
Member

@jdannberg -- want to practice reviewing patches with this one? ;-)

/** House cleaning. */
~IDAInterface();

/** Declare parameters for this class to function properly. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking at the test, i would list here explicitly all the parameters which will be declared. Otherwise users are forced to dig into the source code to see what is actually happening inside to be able to use this function.
I would take the output of ParameterHandler::print_parameters().

{
prm.add_parameter("Initial step size",initial_step_size);

prm.add_parameter("Min step size", min_step_size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since you say Maximum elsewhere, please use Minimum here.


prm.add_parameter("Final time", final_time);

prm.add_parameter("Time units between each output", output_period);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not being a native speaker, i perceive units as units of time (second, hours, etc), thus the description is confusing IMO. Maybe change to Time interval between each output?

"in the local error test.");

prm.add_parameter("Initial condition type", ic_type,
"This is one of the following thress options for the "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thress

Patterns::Selection("none|use_y_diff|use_y_dot"));

prm.add_parameter("Initial condition type after restart", reset_type,
"This is one of the following thress options for the "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thress

@davydden davydden added the WIP label Aug 15, 2017
@davydden
Copy link
Contributor

@luca-heltai please also add a quick test for the new interface, see #3230

@bangerth
Copy link
Member

@luca-heltai ?

@luca-heltai
Copy link
Member Author

I'm still off the grid with only my phone (and my family :-)). As soon as I'm back to Trieste I'll fix all comments, and add some more stuff.

@bangerth
Copy link
Member

OK, no rush. Enjoy the time!

@luca-heltai luca-heltai mentioned this pull request Sep 5, 2017
22 tasks
@luca-heltai luca-heltai removed the WIP label Sep 5, 2017
@luca-heltai
Copy link
Member Author

I think I have addressed all of @davydden requests. If this is looking good, I'll add to sundials directory also the interfaces to the general nonlinear solver (KINSOL), general ODE solver (CVODE), and general implicit explicit time stepper (ARKODE) with respective tests.

@luca-heltai luca-heltai mentioned this pull request Sep 5, 2017
6 tasks
Copy link
Member

@bangerth bangerth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments.

You do a lot of vector allocation/deallocations in order to copy things back and forth. Could one use something like GrowingVectorMemory instead, so that we can re-use these vectors?

@@ -0,0 +1,74 @@
//-----------------------------------------------------------
//
// Copyright (C) 2015 by the deal.II authors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to adjust the year.

Do we want to stick with the directory name sundials/? Or should we go with something more generic, say odesolvers/?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sundials offers also nonlinear solvers and dae solvers (IDA is a dae solver, for example, not an ode solver...). I'd stick to sundials.

Copy link
Contributor

@davydden davydden Sep 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i agree with @luca-heltai . Eventually we may have more interfaces to other libs which contain different types of solvers so i would group headers based on the library name.

#ifdef DEAL_II_WITH_MPI

#ifdef DEAL_II_WITH_TRILINOS
void copy(TrilinosWrappers::MPI::Vector &dst, const N_Vector &src);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You choose the vmult convention of saying copy(dst,src) (which mirrors dst = src). But that's not what std::copy does, for example, nor what most of the rest of the deal.II functions do. Thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept this in an internal namespace, because ideally we should get rid of all these in favour of ReadWriteVector and VectorSpaceVector objects. All copy functions should disappear.

* \end{cases}
* \f]
*
* where \f$y,\dot y\f$ are vectors in \f$\R^n\f$, \f$t\f$ is often the time (but can
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to use \f (in fact, it is wrong) since we automatically expand $ to \f$.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copyed from deal2lkit... there we don't have this auto-magic expansion... :) I'll fix this.

* also be a parametric quantity), and
* \f$F:\R\times\R^n\times\R^n\rightarrow\R^n\f$. Such problem is solved
* using Newton iteration augmented with a line search global
* strategy. The integration method used in ida is the variable-order,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ida -> IDA

* the BDF of order \f$q\f$ given by the multistep formula
*
* \f[
* \sum\limits_{i=0}^q \alpha_{n,i}\,y_{n-i}=h_n\,\dot y_n\, ,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\limit? (or maybe I just don't know the command?)

use_local_tolerances(use_local_tolerances),
ida_mem(nullptr),
communicator(Utilities::MPI::duplicate_communicator(mpi_comm)),
pcout(std::cout, Utilities::MPI::this_mpi_process(mpi_comm)==0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we do this differently, for example via a signal?

next_time += output_period;
if (verbose)
{
pcout << " "//"\r"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the commented out part

<< std::setw(5) << next_time
<< std::endl;
}
status = IDASolve(ida_mem, next_time, &t, yy, yp, IDA_NORMAL);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a check of the return value here?

status = IDASolve(ida_mem, next_time, &t, yy, yp, IDA_NORMAL);

status = IDAGetLastStep(ida_mem, &h);
AssertThrow(status == 0, ExcMessage("Error in IDA Solver"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be nice to output the error code. I think there is already something like AssertMPI or Assert(PETSc) that you could steal for here.

// double frac = 0;
int k = 0;
IDAGetLastOrder(ida_mem, &k);
// frac = std::pow((double)k,2.);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the commented out part

@luca-heltai luca-heltai force-pushed the ida-interface branch 2 times, most recently from 16ab532 to d9cf16c Compare September 8, 2017 15:00
@luca-heltai
Copy link
Member Author

I think this is ready for review. As soon as I have some more time, I'll add more of the functionality provided in IDA to this class (with additional tests).

Copy link
Contributor

@davydden davydden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor suggestions from my side.

{

/**
* Interface to SUNDIALS IDA (Implicit Differential-Algebraic) solver.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe introduce abbreviation here:Implicit Differential-Algebraic (IDA) and then you can use it below?

const bool &use_local_tolerances = false);

/**
* House cleaning.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency with other classes, i would write Destructor.

virtual void add_parameters(ParameterHandler &prm);

/**
* Evolve. This function returns the final number of steps.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe Evolve -> Integrate differential-dlgebraic equations?

* called when the simulation start and when the user returns true to a
* call to solver_should_restart().
*
* By default solver_should_restart returns false. If the user needs to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solver_should_restart()

/**
* Minimum step size.
*/
double min_step_size;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency with the two above minimum_step_size?

/**
* Absolute error tolerance for adaptive time stepping.
*/
double abs_tol;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

absolute_tolerance

/**
* Relative error tolerance for adaptive time stepping.
*/
double rel_tol;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

relative_tolerance

/**
* Maximum order of BDF.
*/
unsigned int max_order;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maximum_order

const unsigned int &max_order = 5,
const double &output_period = .1,
const bool &ignore_algebraic_terms_for_errors = true,
const std::string &ic_type = "none",
Copy link
Contributor

@davydden davydden Sep 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would switch ic_type and reset_typeto enumerators and only internally convert to std::string to provide the correct input to Sundials. Same for class private variables.

* Output stream. If run in parallel, only processor zero will
* output verbose information about time steps.
*/
ConditionalOStream pcout;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dealii/dealii if I understand correctly we are moving away form writing anything from dealii's classes and instead provide functions for optional output

* Those options are set as default value in the ParameterHandler object
* `prm`.
*/
virtual void add_parameters(ParameterHandler &prm);
Copy link
Contributor

@davydden davydden Sep 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an alternative is to move those into an auxiliary class AdditionalData which can declare and read things from ParameterHandler and has a constructor with default values. Then you can easily extend the number of parameters later without breaking constructor interface of the main class.

What I find more important is that you can then make all private fixed parameter members const.

*
* That is $F(y', y, t) = y' + A y = 0 $
*
* where
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop the empty line

* \end{matrix}
* \f]
*
* and $y(0)=(0, k)$, $y'(0) = (k, 0)$
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here.

period at the end of the sentence

* and $y(0)=(0, k)$, $y'(0) = (k, 0)$
*
* The exact solution is $y_0(t) = \sin(k t)$, $y_1(t) = y_0'(t) = k \cos(k t)$,
* $y_1'(t) = -k^2 \sin(k t)$
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

period. same in the following line

std::function<int(const double t,
const VectorType &y,
const VectorType &y_dot,
const double alpha)> setup_jacobian;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the function only takes const arguments, how does it actually setup a jacobian? Can you say when this function is called, and where the jacobian it sets up is stored?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is the user's responsability to decide where to store the Jacobian. This class is agnostic on what the user wants to do, and does not enforce it. I'll document this a little better. The user should make sure that they have a way of solving for J = alpha dF/dy_dot + dF/dy after a call to this function is made. If they want to store a matrix, or setup a matrix free computation, it is their responsability, and this class should not care...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now documented.

* - <0: Unrecoverable error the computation will be aborted and an assertion
* will be thrown.
*/
std::function<int(const VectorType &rhs, VectorType &dst)> solve_jacobian_system;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you say what the function arguments mean, and that the function is supposed to compute dst = J^{-1} rhs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. I don't know why it does not show up here.

std::function<void (const double t,
const VectorType &sol,
const VectorType &sol_dot,
const unsigned int step_number)> output_step;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you wanted to update the description (and maybe name) to state when the function will be called and what it is supposed to do.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

Copy link
Contributor

@davydden davydden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for following up the comments 👍

@luca-heltai
Copy link
Member Author

I've rebased and squashed to a smaller number of commits. Not as good as @drwells git-history (from his commits it looks like he always get things right the first time! :) ...) but this should be small enough.

I think we are now ready.

@bangerth
Copy link
Member

OK to merge once the tester is happy.

/run-tests

@luca-heltai luca-heltai merged commit 1074f8c into dealii:master Sep 16, 2017
@luca-heltai luca-heltai deleted the ida-interface branch September 16, 2017 04:44
@bangerth
Copy link
Member

In reference to #5027.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants