Skip to content

Packages

Vedant Dhruv edited this page Dec 8, 2022 · 61 revisions

A brief intro to packages in KHARMA is provided here; if you're interested in the details, we expound on KHARMA's packages on this page.

Packages are Parthenon's way of introducing modularity in the code in the way of physics and features. Each package has its own namespace within which we define its local variables, global constants (via the params object, an instance of parthenon::Params), its functions, and its tasks.

Unless marked private, packages can access variables declared in other packages. The ability to share variables eliminates the need to save multiple copies of the same variable. Probably the best example of this is the fluid adiabatic index gamma, a constant declared in the GRMHD package, which can be pulled like,

auto gam = pmb->packages.Get("GRMHD")->Param<Real>("gamma");

Every package has an Initialize method declared in its namespace where its variables and constants are registered. The ProcessPackages function defined in the KHARMA namespace loads the required packages during startup. As explained in the section on the ImEx driver, the implicit package is loaded by default if the driver is ImEx. Additionally, KHARMA initializes the GRMHD, Globals and floors package by default. The remainder of the packages are initialized only if specified during runtime. If you've written a new package, you must add its Initialize method to the packages object here.

In additional to global constants that are available through the params object, packages can also include variables that are defined over the entire mesh (also called fields). The variables contain two kinds of information - metadata and data. The metadata contains all the information about the variable, for eg. its name, size, datatype and any other additional info about the variable that facilitates accessing and manipulating the data. The metadata is specified through a vector of MetadataFlags. For example have a look at the following definition of a field in the implicit package.

Metadata m_real = Metadata({Metadata::Real, Metadata::Cell, Metadata::Derived, Metadata::OneCopy});
pkg->AddField("solve_norm", m_real);

Here we have defined an object of Parthenon's Metadata class called m_real by called Metadata's constructor. We've provided a MetadataFlag vector that specifies four flags, Metadata::Real tells it that the field defined by this metadata will consist of Reals, Metadata::Cell clarifies that array of Reals will reside at the cell centers, Metadata::Derived explains that the data in this array can be computed on-the-fly from a more fundamental state of variables, and finally Metadata::OneCopy tells Parthenon that any field defined with this metadata will be shared between stages (recall that we have a multistage driver). The Parthenon docs have a page that lists all the metadata flags available. The second line in the code excerpt above defines a field solve_norm in the implicit package with m_real as its metadata.

Clone this wiki locally