Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here is the source code for a fourth order composition method based on the Verlet scheme. A linear regression of $\log_{10}(\Delta t)$ vs. $\log_{10}(Error)$ will show a slope of 4, as expected from theory (see the graph below). More information can be found <a href="http://www.sciencedirect.com/science/article/pii/0375960190900923" rel="nofollow noreferrer">here</a>, <a href="http://www.cambridge.org/us/academic/subjects/mathematics/computational-science/simulating-hamiltonian-dynamics" rel="nofollow noreferrer">here</a> or <a href="http://www.springer.com/mathematics/computational+science+&amp;+engineering/book/978-3-540-30663-4" rel="nofollow noreferrer">here</a>. </p> <pre><code>#include &lt;cmath&gt; #include &lt;iostream&gt; using namespace std; const double total_time = 5e3; // Parameters for the potential. const double sigma = 1.0; const double sigma6 = pow(sigma, 6.0); const double epsilon = 1.0; const double four_epsilon = 4.0 * epsilon; // Constants used in the composition method. const double alpha = 1.0 / (2.0 - cbrt(2.0)); const double beta = 1.0 - 2.0 * alpha; static double force(double q, double&amp; potential); static void verlet(double dt, double&amp; q, double&amp; p, double&amp; force, double&amp; potential); static void composition_method(double dt, double&amp; q, double&amp; p, double&amp; f, double&amp; potential); int main() { const double q0 = 1.5, p0 = 0.1; double potential; const double f0 = force(q0, potential); const double total_energy_exact = p0 * p0 / 2.0 + potential; for (double dt = 1e-2; dt &lt;= 5e-2; dt *= 1.125) { const long steps = long(total_time / dt); double q = q0, p = p0, f = f0; double total_energy_average = total_energy_exact; for (long step = 1; step &lt;= steps; ++step) { composition_method(dt, q, p, f, potential); const double total_energy = p * p / 2.0 + potential; total_energy_average += total_energy; } total_energy_average /= double(steps); const double err = fabs(total_energy_exact - total_energy_average); cout &lt;&lt; log10(dt) &lt;&lt; "\t" &lt;&lt; log10(err) &lt;&lt; endl; } return 0; } double force(double q, double&amp; potential) { const double r2 = q * q; const double r6 = r2 * r2 * r2; const double factor6 = sigma6 / r6; const double factor12 = factor6 * factor6; potential = four_epsilon * (factor12 - factor6); return -four_epsilon * (6.0 * factor6 - 12.0 * factor12) / r2 * q; } void verlet(double dt, double&amp; q, double&amp; p, double&amp; f, double&amp; potential) { p += dt / 2.0 * f; q += dt * p; f = force(q, potential); p += dt / 2.0 * f; } void composition_method(double dt, double&amp; q, double&amp; p, double&amp; f, double&amp; potential) { verlet(alpha * dt, q, p, f, potential); verlet(beta * dt, q, p, f, potential); verlet(alpha * dt, q, p, f, potential); } </code></pre> <p><img src="https://i.stack.imgur.com/v2cXm.png" alt="Order comparison"></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload