73 #ifndef MFEM_USE_SUNDIALS
74 #error This example requires that MFEM is built with MFEM_USE_SUNDIALS=YES
84 AdvDiffSUNDIALS(
int ydot_dim,
int ybdot_dim,
Vector p,
88 ess_tdof_list(ess_tdof),
91 M_solver(fes->GetComm())
95 cout <<
"Essential tdofs: " << endl;
96 ess_tdof_list.Print();
100 m->Assemble(skip_zeros);
101 m->Finalize(skip_zeros);
113 k->Assemble(skip_zeros);
114 k->Finalize(skip_zeros);
119 k1->Assemble(skip_zeros);
120 k1->Finalize(skip_zeros);
122 M = m->ParallelAssemble();
126 K = k->ParallelAssemble();
130 K_adj = k1->ParallelAssemble();
134 M_prec.SetType(HypreSmoother::Jacobi);
135 M_solver.SetPreconditioner(M_prec);
136 M_solver.SetOperator(*M);
138 M_solver.SetRelTol(1e-14);
139 M_solver.SetAbsTol(0.0);
140 M_solver.SetMaxIter(1000);
141 M_solver.SetPrintLevel(0);
147 virtual void AdjointRateMult(
const Vector &y,
Vector &yB,
150 virtual int SUNImplicitSetup(
const Vector &y,
151 const Vector &fy,
int jok,
int *jcur,
154 virtual int SUNImplicitSolve(
const Vector &
b,
Vector &x,
double tol);
156 virtual void QuadratureSensitivityMult(
const Vector &y,
const Vector &yB,
199 return x[0]*(2. - x[0])*exp(2.*x[0]);
202 int main(
int argc,
char *argv[])
206 MPI_Init(&argc, &argv);
207 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
208 MPI_Comm_rank(MPI_COMM_WORLD, &myid);
211 int ser_ref_levels = 0;
212 int par_ref_levels = 0;
213 double t_final = 2.5;
216 bool step_mode =
true;
219 cout.precision(precision);
223 args.
AddOption(&mx,
"-m",
"--mx",
"The number of mesh elements in the x-dir");
224 args.
AddOption(&ser_ref_levels,
"-r",
"--refine",
225 "Number of times to refine the mesh uniformly.");
226 args.
AddOption(&step_mode,
"-a",
"--adams",
"-no-a",
"--no-adams",
227 "A switch to toggle between CV_ADAMS, and CV_BDF stepping modes");
228 args.
AddOption(&t_final,
"-tf",
"--t-final",
229 "Final time; start time is 0.");
230 args.
AddOption(&dt,
"-dt",
"--time-step",
250 Mesh mesh = Mesh::MakeCartesian1D(mx+1, 2.);
256 for (
int lev = 0; lev < ser_ref_levels; lev++)
263 for (
int lev = 0; lev < par_ref_levels; lev++)
275 cout <<
"Number of unknowns: " << global_vSize << endl;
290 cout <<
"Init u: " << endl;
299 essential_attr[0] = 1;
300 essential_attr[1] = 1;
301 fes->GetEssentialTrueDofs(essential_attr, ess_tdof_list);
304 AdvDiffSUNDIALS adv(U->
Size(), U->
Size(),
p, fes, ess_tdof_list);
312 step_mode ? CV_ADAMS : CV_BDF);
318 double reltol = 1e-8, abstol = 1e-6;
322 int checkpoint_steps = 50;
328 for (
int ti = 0; !done; )
330 double dt_real = max(dt, t_final - t);
331 cvodes->
Step(*U, t, dt_real);
334 done = (t >= t_final - 1e-8*dt);
336 if (done && myid == 0)
345 cout <<
"Final Solution: " << t << endl;
348 cout <<
"u (" << myid <<
"):" << endl;
351 MPI_Barrier(MPI_COMM_WORLD);
363 cout <<
"g: " << g << endl;
383 double dt_real = max(dt, t);
384 cvodes->
StepB(*V, t, dt_real);
387 cout <<
"t: " << t << endl;
390 cout <<
"v (" << myid <<
"):" << endl;
393 MPI_Barrier(MPI_COMM_WORLD);
398 MPI_Barrier(MPI_COMM_WORLD);
401 cout <<
"sensitivity:" << endl;
423 x1.SetSubVector(ess_tdof_list, 0.0);
432 int AdvDiffSUNDIALS::SUNImplicitSetup(
const Vector &y,
434 int jok,
int *jcur,
double gamma)
441 Mf =
Add(1., *M, -gamma, *K);
448 int AdvDiffSUNDIALS::SUNImplicitSolve(
const Vector &
b,
Vector &x,
double tol)
455 prec.
SetType(HypreSmoother::Jacobi);
456 solver.SetPreconditioner(prec);
457 solver.SetOperator(*Mf);
458 solver.SetRelTol(1E-14);
459 solver.SetMaxIter(1000);
467 void AdvDiffSUNDIALS::AdjointRateMult(
const Vector &y,
Vector & yB,
475 M_solver.Mult(z, yBdot);
479 void AdvDiffSUNDIALS::QuadratureSensitivityMult(
const Vector &y,
506 Vector p2vec(pfes->GetParMesh()->SpaceDimension()); p2vec = 1.;
520 double dp1_result =
InnerProduct(pfes->GetComm(), yB, b1);
521 double dp2_result =
InnerProduct(pfes->GetComm(), yB, b2);
523 qBdot[0] = -dp1_result;
524 qBdot[1] = -dp2_result;
int Size() const
Return the logical size of the array.
void EliminateRowsCols(const Array< int > &rows_cols, const HypreParVector &X, HypreParVector &B)
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
Class for domain integration L(v) := (f, v)
Conjugate gradient method.
virtual void StepB(Vector &w, double &t, double &dt)
Solve one adjoint time step.
void SetSStolerances(double reltol, double abstol)
Set the scalar relative and scalar absolute tolerances.
ParMesh * GetParMesh() const
A coefficient that is constant across space and time.
Vector coefficient that is constant in space and time.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
int Size() const
Returns the size of the vector.
Abstract parallel finite element space.
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
virtual void Step(Vector &x, double &t, double &dt)
void UseSundialsLinearSolverB()
Use built in SUNDIALS Newton solver.
void SetSStolerancesB(double reltol, double abstol)
Tolerance specification functions for the adjoint problem.
void InitAdjointSolve(int steps, int interpolation)
Initialize Adjoint.
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void InitQuadIntegrationB(mfem::Vector &qB0, double reltolQB=1e-3, double abstolQB=1e-8)
Initialize Quadrature Integration (Adjoint)
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Parallel smoothers in hypre.
void PrintUsage(std::ostream &out) const
Print the usage message.
int SpaceDimension() const
Wrapper for hypre's parallel vector class.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
double p(const Vector &x, double t)
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
double InnerProduct(HypreParVector *x, HypreParVector *y)
void InitB(TimeDependentAdjointOperator &f_)
Initialize the adjoint problem.
void PrintOptions(std::ostream &out) const
Print the options.
HypreParVector * GetTrueDofs() const
Returns the true dofs in a new HypreParVector.
void Clear()
Clear the contents of the Mesh.
A general function coefficient.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0) const
Computes y = alpha * A * x + beta * y.
Arbitrary order H1-conforming (continuous) finite elements.
void PrintInfo() const
Print various CVODE statistics.
void Init(TimeDependentAdjointOperator &f_)
double u(const Vector &xvec)
Class for parallel grid function.
Wrapper for hypre's ParCSR matrix class.
double u_init(const Vector &x)
Class for parallel meshes.
void SetType(HypreSmoother::Type type, int relax_times=1)
Set the relaxation type and number of sweeps.
void EvalQuadIntegrationB(double t, Vector &dG_dp)
Evaluate Quadrature solution.
void UseSundialsLinearSolver()
Attach SUNDIALS GMRES linear solver to CVODE.
void SetMaxNSteps(int steps)
Set the maximum number of time steps.
bool Good() const
Return true if the command line options were parsed successfully.