79 class LinearScaleOperator :
public Operator
86 LinearScaleOperator(
const Vector &weight)
89 for (
int i = 0; i < width; i++) { grad(0, i) = w(i); }
105 class TanhSumOperator :
public Operator
111 TanhSumOperator(
int size) :
Operator(1, size), grad(1, width) { }
115 y(0) = std::tanh(x.
Sum());
120 const double ts = std::tanh(x.
Sum());
121 const double dtanh = 1.0 - ts * ts;
122 for (
int i = 0; i < width; i++) { grad(0, i) = dtanh; }
137 Vector massvec, d_lo, d_hi;
138 const LinearScaleOperator LSoper;
139 const TanhSumOperator TSoper;
142 OptimizedTransportProblem(
const Vector &xho,
const Vector &w,
double mass,
145 x_HO(xho), massvec(1), d_lo(1), d_hi(1),
146 LSoper(w), TSoper(w.Size())
150 SetEqualityConstraint(massvec);
153 d_lo(0) = std::tanh(xmin.
Sum());
154 d_hi(0) = std::tanh(xmax.
Sum());
155 MFEM_ASSERT(d_lo(0) < d_hi(0),
156 "The bounds produce an infeasible optimization problem");
157 SetInequalityConstraint(d_lo, d_hi);
159 SetSolutionBounds(xmin, xmax);
162 virtual double CalcObjective(
const Vector &x)
const
165 for (
int i = 0; i < input_size; i++)
167 const double d = x(i) - x_HO(i);
173 virtual void CalcObjectiveGrad(
const Vector &x,
Vector &grad)
const
175 for (
int i = 0; i < input_size; i++) { grad(i) = x(i) - x_HO(i); }
211 int main(
int argc,
char *argv[])
216 const char *mesh_file =
"../../data/periodic-hexagon.mesh";
219 int ode_solver_type = 3;
220 double t_final = 1.0;
222 bool visualization =
true;
228 cout.precision(precision);
231 args.
AddOption(&mesh_file,
"-m",
"--mesh",
232 "Mesh file to use.");
234 "Problem setup to use. See options in velocity_function().");
235 args.
AddOption(&ref_levels,
"-r",
"--refine",
236 "Number of times to refine the mesh uniformly.");
238 "Order (degree) of the finite elements.");
240 "Nonlinear optimizer: 1 - SLBQP,\n\t"
242 args.
AddOption(&ode_solver_type,
"-s",
"--ode-solver",
243 "ODE solver: 1 - Forward Euler,\n\t"
244 " 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
245 args.
AddOption(&t_final,
"-tf",
"--t-final",
246 "Final time; start time is 0.");
247 args.
AddOption(&dt,
"-dt",
"--time-step",
249 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
250 "--no-visualization",
251 "Enable or disable GLVis visualization.");
252 args.
AddOption(&visit,
"-visit",
"--visit-datafiles",
"-no-visit",
253 "--no-visit-datafiles",
254 "Save data files for VisIt (visit.llnl.gov) visualization.");
255 args.
AddOption(&binary,
"-binary",
"--binary-datafiles",
"-ascii",
257 "Use binary (Sidre) or ascii format for VisIt data files.");
258 args.
AddOption(&vis_steps,
"-vs",
"--visualization-steps",
259 "Visualize every n-th timestep.");
270 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
276 switch (ode_solver_type)
279 case 2: ode_solver =
new RK2Solver(1.0);
break;
281 case 4: ode_solver =
new RK4Solver;
break;
282 case 6: ode_solver =
new RK6Solver;
break;
284 cout <<
"Unknown ODE solver type: " << ode_solver_type <<
'\n';
293 for (
int lev = 0; lev < ref_levels; lev++)
308 cout <<
"Number of unknowns: " << fes.
GetVSize() << endl;
344 ofstream omesh(
"ex9.mesh");
345 omesh.precision(precision);
347 ofstream osol(
"ex9-init.gf");
348 osol.precision(precision);
359 #ifdef MFEM_USE_SIDRE
362 MFEM_ABORT(
"Must build with MFEM_USE_SIDRE=YES for binary output.");
379 char vishost[] =
"localhost";
381 sout.
open(vishost, visport);
384 cout <<
"Unable to connect to GLVis server at "
385 << vishost <<
':' << visport << endl;
386 visualization =
false;
387 cout <<
"GLVis visualization disabled.\n";
391 sout.precision(precision);
392 sout <<
"solution\n" << *mesh << u;
395 cout <<
"GLVis visualization paused."
396 <<
" Press space (in the GLVis window) to resume it.\n";
410 ode_solver->
Init(adv);
413 const double vol0 = M_rowsums * u;
416 for (
int ti = 0; !done; )
418 double dt_real = min(dt, t_final - t);
419 adv.SetTimeStep(dt_real);
420 ode_solver->
Step(u, t, dt_real);
423 done = (t >= t_final - 1e-8*dt);
425 if (done || ti % vis_steps == 0)
427 cout <<
"time step: " << ti <<
", time: " << t << endl;
431 sout <<
"solution\n" << *mesh << u << flush;
444 const double max_error = u.ComputeMaxError(u0),
445 l1_error = u.ComputeL1Error(u0),
446 l2_error = u.ComputeL2Error(u0);
447 std::cout <<
"Linf error = " << max_error << endl
448 <<
"L1 error = " << l1_error << endl
449 <<
"L2 error = " << l2_error << endl;
452 const double vol = M_rowsums * u;
453 std::cout <<
"Vol error = " << vol - vol0 << endl;
458 ofstream osol(
"ex9-final.gf");
459 osol.precision(precision);
476 M(_M), K(_K),
b(_b), M_prec(), M_solver(), z(_M.Size()),
477 bf(_bf), M_rowsums(M_rs)
492 const int dofs = x.
Size();
493 Vector y_min(dofs), y_max(dofs);
495 for (
int i = 0, k = 0; i < dofs; i++)
499 for (
int end = In[i+1]; k < end; k++)
502 if (x(j) > x_i_max) { x_i_max = x(j); }
503 if (x(j) < x_i_min) { x_i_min = x(j); }
508 for (
int i = 0; i < dofs; i++)
510 y_min(i) = (y_min(i) - x(i) ) / dt;
511 y_max(i) = (y_max(i) - x(i) ) / dt;
520 const double mass_y = 0.0;
524 const int max_iter = 500;
525 const double rtol = 1.e-7;
533 optsolver = tmp_opt_ptr;
535 MFEM_ABORT(
"MFEM is not built with HiOp support!");
547 OptimizedTransportProblem ot_prob(y, M_rowsums, mass_y, y_min, y_max);
554 optsolver->
Mult(y, y_out);
569 for (
int i = 0; i <
dim; i++)
583 case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.);
break;
584 case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
593 const double w = M_PI/2;
596 case 1: v(0) = 1.0;
break;
597 case 2: v(0) = w*X(1); v(1) = -w*X(0);
break;
598 case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0;
break;
605 const double w = M_PI/2;
606 double d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
610 case 1: v(0) = 1.0;
break;
611 case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0);
break;
612 case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0;
break;
626 for (
int i = 0; i <
dim; i++)
640 return (X(0) > -0.15 && X(0) < 0.15) ? 1.0 : 0.0;
645 double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
648 const double s = (1. + 0.25*cos(2*M_PI*X(2)));
652 return ( erfc(w*(X(0)-cx-rx))*erfc(-w*(X(0)-cx+rx)) *
653 erfc(w*(X(1)-cy-ry))*erfc(-w*(X(1)-cy+ry)) )/16;
659 double x_ = X(0), y_ = X(1), rho, phi;
662 return pow(sin(M_PI*rho),2)*sin(3*phi);
666 const double f = M_PI;
667 return sin(f*X(0))*sin(f*X(1));
void SetPrecision(int prec)
Set the precision (number of digits) used for the text output of doubles.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
virtual void Print(std::ostream &out=mfem::out) const
Conjugate gradient method.
Class for grid function - Vector with associated FE space.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
Data type for scaled Jacobi-type smoother of sparse matrix.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Base abstract class for first order time dependent operators.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void GetBoundingBox(Vector &min, Vector &max, int ref=2)
Returns the minimum and maximum corners of the mesh bounding box.
int * GetJ()
Return the array J.
virtual void Step(Vector &x, double &t, double &dt)=0
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in]...
virtual void Init(TimeDependentOperator &f)
Associate a TimeDependentOperator with the ODE solver.
virtual void SetTime(const double _t)
Set the current time.
Data type dense matrix using column-major storage.
int Size() const
Returns the size of the vector.
Abstract class for solving systems of ODEs: dx/dt = f(x,t)
int * GetI()
Return the array I.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
int main(int argc, char *argv[])
FE_Evolution(FiniteElementSpace &_vfes, Operator &_A, SparseMatrix &_Aflux)
Data collection with Sidre routines following the Conduit mesh blueprint specification.
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void SetLinearConstraint(const Vector &_w, double _a)
void SetPrintLevel(int print_lvl)
virtual void Save()
Save the collection to disk.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Data collection with VisIt I/O routines.
void SetMaxIter(int max_it)
virtual void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
void PrintUsage(std::ostream &out) const
void SetTime(double t)
Set physical time (for time-dependent simulations)
void SetTimeStep(double _dt)
The classical explicit forth-order Runge-Kutta method, RK4.
void SetAbsTol(double atol)
void SetRelTol(double rtol)
void velocity_function(const Vector &x, Vector &v)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
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)
Third-order, strong stability preserving (SSP) Runge-Kutta method.
Adapts the HiOp functionality to the MFEM OptimizationSolver interface.
virtual void Mult(const Vector &x, Vector &y) const
Perform the action of the operator: y = k = f(x, t), where k solves the algebraic equation F(x...
void SetBounds(const Vector &_lo, const Vector &_hi)
NURBSExtension * NURBSext
Optional NURBS mesh extension.
Abstract solver for OptimizationProblems.
virtual void Mult(const Vector &xt, Vector &x) const =0
Operator application: y=A(x).
void PrintOptions(std::ostream &out) const
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
virtual void ProjectCoefficient(Coefficient &coeff)
int open(const char hostname[], int port)
double u0_function(const Vector &x)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
class for C-function coefficient
void SetK(SparseMatrix &_K)
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
The classical forward Euler method.
virtual void SetOptimizationProblem(const OptimizationProblem &prob)
double Sum() const
Return the sum of the vector entries.
double inflow_function(const Vector &x)
void GetRowSums(Vector &x) const
For all i compute .
Arbitrary order "L2-conforming" discontinuous finite elements.