Quick Start

MISO provides the base class miso::mhd::ModelBase for building a model, and various test problems are realized by editing it. The further a problem departs from what ModelBase assumes, the more code you have to write.

In the following, we explain using the main program of the test problem demo/mhd2d_vortex as an example. This problem is implemented simply by setting the initial condition as follows.

struct InitialCondition {
  eos::IdealEOS<Real> &eos;

  explicit InitialCondition(eos::IdealEOS<Real> &eos) : eos(eos) {}

  // The signature must not be changed as it is called inside miso::mhd::MHD.
  void apply(mhd::FieldsView<Real> qq, GridView<const Real> grid) const {
    const Real pr = 1.0 / eos.gm;
    const Real b0 = util::sqrt(4.0 * pi<Real>) / eos.gm;
    const Real v0 = 1.0;

    for (int k = 0; k < grid.k_total; ++k) {
      for (int j = 0; j < grid.j_total; ++j) {
        for (int i = 0; i < grid.i_total; ++i) {
          qq.ro(i, j, k) = 1.0;
          qq.ei(i, j, k) = eos.roprtoei(qq.ro(i, j, k), pr);
          qq.vx(i, j, k) = -v0 * util::sin(2.0 * pi<Real> * grid.y[j]);
          qq.vy(i, j, k) = +v0 * util::sin(2.0 * pi<Real> * grid.x[i]);
          qq.vz(i, j, k) = 0.0;
          qq.bx(i, j, k) = -b0 * util::sin(2.0 * pi<Real> * grid.y[j]);
          qq.by(i, j, k) = +b0 * util::sin(4.0 * pi<Real> * grid.x[i]);
          qq.bz(i, j, k) = 0.0;
          qq.ph(i, j, k) = 0.0;
        }
      }
    }
  }
};

Here, miso::eos::IdealEOS<Real> is a class for computing the equation of state of an ideal gas. miso::mhd::FieldsView is a class whose members are the basic variables of the MHD equations, such as density and the velocity field, and miso::GridView is a class for the computational grid. With both, you can access each array element as in qq.ro(i, j, k) and grid.x[i] above. Note that the function apply is called from ModelBase, so you cannot change its signature (arguments, return type, etc.).

This initial condition can be incorporated into ModelBase as follows.

struct Model : public mhd::ModelBase<Model, Real, Backend> {
  eos::IdealEOS<Real> eos;
  InitialCondition ic;
  mhd::EmptyBoundaryCondition<Real> bc;
  mhd::EmptySourceTerm<Real> src;

  Model(Config &config) : ModelBase(config), eos(config), ic(eos), bc(), src() {}
};

Here, miso::mhd::EmptyBoundaryCondition is a boundary condition that does nothing. Use it only when periodic boundary conditions are sufficient in all directions. Whether the computational domain is periodic can be specified in the domain section of the configuration file config.yaml as follows.

domain:
  periodic:
    x: true
    y: true
    z: true

In MHD simulations, you may want to add a source term to the right-hand side of the equations, for example an external force such as gravity or a heating term such as radiative cooling. miso::mhd::EmptySourceTerm above is a class to use when there is no source term on the right-hand side.

miso::mhd::ModelBase, the parent class of Model, actually performs the following initialization.

  • Reading the configuration file (config.yaml, etc.)

  • Setting up MPI and CUDA

  • Initializing the computational grid miso::Grid

  • Initializing the MHD class miso::mhd::MHD

In addition, the Model of the test problem demo/mhd2d_vortex initializes the equation of state, the initial condition, the boundary condition, and the source term.

The main function initializes miso, reads the configuration file config.yaml, and runs the Model as follows.

int main(int argc, char **argv) {
  // Initialize MPI and CUDA environments
  Env env(argc, argv);

  // Read configuration file
  auto config_path = parse_config_filepath(argc, argv);
  Config config(config_path.value_or("./config.yaml"));

  // Run simulation
  Model model(config);
  model.run();
}

Specifically, ModelBase.run() performs the following computation.

  • Applying the initial condition ic to the MHD variables

  • Writing the information of the configuration file and the computational grid grid (miso::Grid) to files

  • Writing the MHD variables qq (miso::mhd::Fields) to files at the initial state and at each time step

  • Loading existing run data (if any)

  • Main loop

    • Evaluating the CFL condition and determining the time step size

    • Time integration of the MHD variables (including applying the boundary condition bc, adding the source term src to the right-hand side, and calling the equation of state eos)

    • Updating the time time (miso::Time)

Here, the initial condition ic, the boundary condition bc, the source term src, and the equation of state eos are meant to be set by the user, and use the variables defined in the child class that inherits from ModelBase.

For how to customize each of them, refer to the test problems in demo. In particular, the magnetosphere problem demo/mhd3d_magnetosphere modifies the initial condition, the boundary condition, the source term, and also the CFL condition, so we recommend it.