77 static double m_ = 1.0;
78 static double k_ = 1.0;
97 int main(
int argc,
char *argv[])
100 Mpi::Init(argc, argv);
102 int num_procs = Mpi::WorldSize();
103 int myid = Mpi::WorldRank();
104 MPI_Comm comm = MPI_COMM_WORLD;
110 bool visualization =
true;
111 bool gnuplot =
false;
115 "Time integration order.");
116 args.
AddOption(&prob_,
"-p",
"--problem-type",
118 "\t 0 - Simple Harmonic Oscillator\n" 120 "\t 2 - Gaussian Potential Well\n" 121 "\t 3 - Quartic Potential\n" 122 "\t 4 - Negative Quartic Potential");
123 args.
AddOption(&nsteps,
"-n",
"--number-of-steps",
124 "Number of time steps.");
125 args.
AddOption(&dt,
"-dt",
"--time-step",
129 args.
AddOption(&k_,
"-k",
"--spring-const",
131 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
132 "--no-visualization",
133 "Enable or disable GLVis visualization.");
134 args.
AddOption(&gnuplot,
"-gp",
"--gnuplot",
"-no-gp",
"--no-gnuplot",
135 "Enable or disable GnuPlot visualization.");
160 q(0) = sin(2.0*M_PI*(
double)myid/num_procs);
161 p(0) = cos(2.0*M_PI*(
double)myid/num_procs);
168 oss <<
"ex20p_" << setfill(
'0') << setw(5) << myid <<
".dat";
169 ofs.open(oss.str().c_str());
170 ofs <<
t <<
"\t" << q(0) <<
"\t" <<
p(0) << endl;
174 int nverts = (visualization) ? 2*num_procs*(nsteps+1) : 0;
175 int nelems = (visualization) ? (nsteps * num_procs) : 0;
176 Mesh mesh(2, nverts, nelems, 0, 3);
178 int *part = (visualization) ? (
new int[nelems]) : NULL;
186 for (
int i = 0; i < nsteps; i++)
196 for (
int j = 0; j < num_procs; j++)
215 ofs <<
t <<
"\t" << q(0) <<
"\t" <<
p(0) <<
"\t" << e[i+1] << endl;
222 for (
int j = 0; j < num_procs; j++)
229 v[0] = 2 * num_procs * i + 2 * j;
230 v[1] = 2 * num_procs * (i + 1) + 2 * j;
231 v[2] = 2 * num_procs * (i + 1) + 2 * j + 1;
232 v[3] = 2 * num_procs * i + 2 * j + 1;
234 part[num_procs * i + j] = j;
240 e_mean /= (nsteps + 1);
242 for (
int i = 0; i <= nsteps; i++)
244 e_var += pow(e[i] - e_mean, 2);
246 e_var /= (nsteps + 1);
247 double e_sd = sqrt(e_var);
249 double e_loc_stats[2];
250 double *e_stats = (myid == 0) ?
new double[2 * num_procs] : (
double*)NULL;
252 e_loc_stats[0] = e_mean;
253 e_loc_stats[1] = e_sd;
254 MPI_Gather(e_loc_stats, 2, MPI_DOUBLE, e_stats, 2, MPI_DOUBLE, 0, comm);
258 cout << endl <<
"Mean and standard deviation of the energy " 259 <<
"for different initial conditions" << endl;
260 for (
int i = 0; i < num_procs; i++)
262 cout << i <<
": " << e_stats[2 * i + 0]
263 <<
"\t" << e_stats[2 * i + 1] << endl;
274 ofs.open(
"gnuplot_ex20p.inp");
275 for (
int i = 0; i < num_procs; i++)
278 ossi <<
"ex20p_" << setfill(
'0') << setw(5) << i <<
".dat";
283 ofs <<
" '" << ossi.str() <<
"' using 1:2 w l t 'q" << i <<
"'," 284 <<
" '" << ossi.str() <<
"' using 1:3 w l t 'p" << i <<
"'," 285 <<
" '" << ossi.str() <<
"' using 1:4 w l t 'H" << i <<
"'";
303 ParMesh pmesh(comm, mesh, part);
310 for (
int i = 0; i <= nsteps; i++)
312 energy[2*i+0] = e[i];
313 energy[2*i+1] = e[i];
320 sock <<
"parallel " << num_procs <<
" " << myid <<
"\n" 321 <<
"solution\n" << pmesh << energy
322 <<
"window_title 'Energy in Phase Space'\n" 323 <<
"keys\n maac\n" <<
"axis_labels 'q' 'p' 't'\n"<< flush;
329 double h = 1.0 - 0.5 / m_ + 0.5 *
p *
p / m_;
333 h += k_ * (1.0 - cos(q));
336 h += k_ * (1.0 - exp(-0.5 * q * q));
339 h += 0.5 * k_ * (1.0 + q * q) * q * q;
342 h += 0.5 * k_ * (1.0 - 0.125 * q * q) * q * q;
345 h += 0.5 * k_ * q * q;
356 y(0) = - k_* sin(x(0));
359 y(0) = - k_ * x(0) * exp(-0.5 * x(0) * x(0));
362 y(0) = - k_ * (1.0 + 2.0 * x(0) * x(0)) * x(0);
365 y(0) = - k_ * (1.0 - 0.25 * x(0) * x(0)) * x(0);
virtual void Init(Operator &P, TimeDependentOperator &F)
int AddQuad(int v1, int v2, int v3, int v4, int attr=1)
void PrintOptions(std::ostream &out) const
Print the options.
void PrintUsage(std::ostream &out) const
Print the usage message.
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)
bool Good() const
Return true if the command line options were parsed successfully.
Abstract parallel finite element space.
void Step(Vector &q, Vector &p, double &t, double &dt) override
int AddVertex(double x, double y=0.0, double z=0.0)
int main(int argc, char *argv[])
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
double p(const Vector &x, double t)
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...
Vector & Set(const double a, const Vector &x)
(*this) = a * x
double hamiltonian(double q, double p, double t)
void FinalizeQuadMesh(int generate_edges=0, int refine=0, bool fix_orientation=true)
Finalize the construction of a quadrilateral Mesh.
Arbitrary order H1-conforming (continuous) finite elements.
Class for parallel grid function.
Class for parallel meshes.
Variable order Symplectic Integration Algorithm (orders 1-4)