In this example we will integrate cos(t), whose analytical solution is sin(t).

Sampling.h

#pragma once

#include "ascent/Link.h"

class Sampling : public asc::Module
{
public:
   double x{}, xd{};

   Sampling(size_t sim);

protected:
   void update();
   void report();
};

Sampling.cpp

#include "Sampling.h"

using namespace std;

Sampling::Sampling(size_t sim) : asc::Module(sim)
{
   addIntegrator(x, xd);
}

void Sampling::update()
{
   cout << "update" << '\n';
   cout << "t " << t << '\n';

   xd = cos(t); // integrated xd will be sin(t)

   if (sample())
      cout << "x at first pass " << x << '\n';
   else
      cout << "x " << x << '\n';

   if (sample(0.13) && !first_update) // sample() will always return true when t == 0.0, we use !first_update here to exclude printing the initial condition
      cout << "x every 0.13: " << x << '\n';

   cout << '\n';
}

void Sampling::report()
{
   cout << "report" << '\n';
   cout << "t " << t << '\n';
   cout << "sin(t) " << sin(t) << '\n';
   cout << "x " << x << '\n' << '\n';
}

Main.cpp

#include "Sampling.h"

int main()
{
   Sampling system(0);
   system.run(0.1, 0.3);

   return 0;
}

Command line output:

  • By default Ascent runs a 4th Order Runge Kutta integrator, so there are four update() calls for every report().
  • But, sample() statements only return true at the first update() call in a step.
  • Notice that the sampling rate of 0.13 is always stepped to exactly (0.13, 0.26) even though these values are between time steps.

    report
    t 0
    sin(t) 0
    x 0
    
    update
    t 0
    x at first pass 0
    
    update
    t 0.05
    x 0.05
    
    update
    t 0.05
    x 0.0499375
    
    update
    t 0.1
    x 0.099875
    
    report
    t 0.1
    sin(t) 0.0998334
    x 0.0998334
    
    update
    t 0.1
    x at first pass 0.0998334
    
    update
    t 0.115
    x 0.114758
    
    update
    t 0.115
    x 0.114734
    
    update
    t 0.13
    x 0.129635
    
    report
    t 0.13
    sin(t) 0.129634
    x 0.129634
    
    update
    t 0.13
    x at first pass 0.129634
    x every 0.13: 0.129634
    
    update
    t 0.165
    x 0.164339
    
    update
    t 0.165
    x 0.164159
    
    update
    t 0.2
    x 0.198683
    
    report
    t 0.2
    sin(t) 0.198669
    x 0.198669
    
    update
    t 0.2
    x at first pass 0.198669
    
    update
    t 0.23
    x 0.228071
    
    update
    t 0.23
    x 0.227879
    
    update
    t 0.26
    x 0.257089
    
    report
    t 0.26
    sin(t) 0.257081
    x 0.257081
    
    update
    t 0.26
    x at first pass 0.257081
    x every 0.13: 0.257081
    
    update
    t 0.28
    x 0.276408
    
    update
    t 0.28
    x 0.276302
    
    update
    t 0.3
    x 0.295523
    
    report
    t 0.3
    sin(t) 0.29552
    x 0.29552