Rat

Using pyRat should feel very similar to using Rat.

Rat workflow

In order to get familiar with Rat it is recommended to first have a look at original C++ code examples in Project-Rat repositories.

The Rat-GUI software also represents the Rat workflow pretty well since it is built around the same Rat C++ libraries. Its use translates quite well to code.

Python code through pyRat should feel quite transparent if familiar with Rat.

Typical projects

Rat projects typically follow a common structure.

The following parts are taken from Rat-Template translation to Python for pyRat available at pyrat/src/pyrat/examples/rat-template

Defining inputs

Most projects starts by defining the geometric inputs and all other operating paramaters for the model. This could be statements defining variables or reading from a file via the command line.

It can look something like this in Python:

time = 0        # [s]
radius = 40e-3  # [m]
dcoil = 10e-3   # [m]
wcable = 12e-3  # [m]
delem = 1e-3    # [m]
operating_current = 200  # [A]
num_sections = 4
num_turns = 100

These parameters are later used when building the models.

Defining models

Models can be composed from several parts depending on the complexity at hand.

Rat offers some predefined classes for generic models such as the ModelRacetrack or ModelSolenoid classes, but more complex models can be built by combining parts.

This is usually done using a cross-section along a path.

A solenoid can then easily be built from a CrossRectangle instance and a PathCircle instance to combine into a model:

# Define solenoid model
path_circle = rat.mdl.PathCircle(
    radius, num_sections, delem
)  # Circular path for solenoid
cross_rectangle = rat.mdl.CrossRectangle(
    0, dcoil, 0, wcable, delem
)  # Rectangle cross section along path
solenoid = rat.mdl.ModelCoil(
    path_circle, cross_rectangle
)  # Model composed of path and cross
solenoid.number_turns = num_turns               # Set number of turns
solenoid.operating_current = operating_current  # Set operating current

This hierarchy can escalade into various models.

Models are can then be used as sources and targets for calculations.

Defining calculations

Calculations are usually defined on model items to compute magnetic properties over points of interest.

Calculations come in many forms: CalcGrid, CalcHarmonics, etc, but they mostly boil down to defining points in 3D space for calculations.

Calculations can easily be created from models:

# Create mesh calculation instance from previous solenoid
calc_mesh = rat.mdl.CalcMesh(solenoid)

Calculations are items just like any other in Rat and need to be run in order to compute anything.

Running calculations

Calculation items come with calc-related methods in order to compute results.

# Run calculations, print info with lg, and save visualization outputs
calc_mesh.calculate_write([time], "./data", lg)

calculate_write is one of these methods: calculating results and storing them into VTK visualization items under a "./data" directory, as well as logging info to the console about the ongoing calculations.

This is the most interactive way to run calculations but one might seek deeper knowledge about the mesh and do some precise post-processing on the resulting values:

# Run calculations and store results in datas item
datas = calc_mesh.calculate_mesh(time, lg)

# Post-process B field of every mesh in datas
for data in datas:

    # Safeguard to ensure B field is accessible
    if data.has("B"):

        # Get target coordinates
        xyz = data.get_target_coords()

        # Get B field data
        B_xyz = data.get_field("B")

        # Compute B field norm
        B_norm = np.linalg.norm(B_xyz, axis=0)

        # Save table into CSV file
        np.savetxt(
            f"{output_dir}/B_data.csv",
            np.vstack((xyz, B_xyz, B_norm)).T,
            delimiter=",",
            header="x,y,z,Bx,By,Bz,B",
        )