Utilities

This page lists supporting public objects that are commonly used with the new Python interface.

Time Integration Solvers

Import built-in solvers from HASEonGPU:

from HASEonGPU import (
    ExplicitEuler,
    Heun,
    Midpoint,
    RungeKutta4,
    FrozenPhiAseRungeKutta4,
    ImplicitEuler,
    ExponentialEuler,
)

Available solvers:

  • ExplicitEuler()

  • Heun()

  • Midpoint()

  • RungeKutta4()

  • FrozenPhiAseRungeKutta4()

  • ImplicitEuler(iterations=8, tolerance=1e-10)

  • ExponentialEuler()

FrozenPhiAseRungeKutta4 computes phiASE once per outer simulation step, then reuses that fixed ASE flux while RK4 re-evaluates the pump and local ASE coupling terms for each stage. Use it to reduce ASE backend cost when a stage-by-stage transport solve is not required.

All solvers implement:

step(rhs, betaCells, time, timeStep)

The return value is a TimeIntegrationResult with:

  • betaCells: updated beta array \(\beta_i\).

  • evaluation: the TimeDerivative used by the solver.

Custom Time Integration

Custom solvers only need the same step method:

class MyEuler:
    def step(self, rhs, betaCells, time, timeStep):
        evaluation = rhs(betaCells, time)
        return TimeIntegrationResult(
            betaCells=betaCells + timeStep * evaluation.derivative,
            evaluation=evaluation,
        )

TimeDerivative contains:

  • betaCells

  • dndtPump

  • dndtAse

  • derivative

  • tau

  • phiAse

  • aseResult

Here dndtPump, dndtAse, and derivative are contributions to \(d\beta/dt\); tau is the fluorescence lifetime \(\tau\), and phiAse is the ASE flux \(\Phi_i\).

VTK Export

vtkWedge writes point or cell data on the wedge mesh to a legacy ASCII VTK file. In a Simulation.onStep callback, pass the TimeStepState to vtkWedge; the state carries the static topology and the dynamic arrays.

Callback use:

def write_vtk(state, output_dir, cladding_absorption):
    vtkWedge(
        output_dir / "fields_{step:03d}.vtk",
        state,
        fields={
            "betaCells": state.betaCells,
            "phiASE": state.phiAse,
            "dndtAse": state.dndtAse,
            "cladAbs": state.phiAse * cladding_absorption,
        },
    )

simulation.onStep(write_vtk, output_dir, 5.5)

Direct use after one step:

state = simulation.step()
vtkWedge("phi.vtk", state)
vtkWedge("fields.vtk", state, field=["phiAse", "dndtAse"])
vtkWedge("named.vtk", state, field={"phi": "phiAse", "dn": "dndtAse"})

For standalone array exports outside a simulation state, pass geometry as a GainMedium or MeshTopology:

vtkWedge("fields.vtk", geometry=medium, fields={"phi": phi, "dn": dndt})

The older callback-factory form is still accepted and can use every to reduce output frequency:

simulation.onStep(vtkWedge("phi_{step:03d}.vtk", medium, every=10))

For new code, prefer an explicit callback when output frequency or derived fields are needed:

def write_every_tenth(state, output_dir):
    if state.step % 10 == 0:
        vtkWedge(output_dir / "phi_{step:03d}.vtk", state)

simulation.onStep(write_every_tenth, output_dir)

The data shape must match either:

  • point data: (numberOfPoints, numberOfLevels)

  • cell data: (numberOfTriangles, numberOfLevels - 1)

Gain Field Export

calcGainFromState calculates small-signal laser gain from a TimeStepState and returns a point-shaped array that can be written directly with vtkWedge:

vtkWedge(
    output_path,
    state,
    fields={
        "gain": calcGainFromState(state, spectra, nTot),
    },
)

Pump Solver Utilities

OneDimensionalZTraversal is the built-in continuous pump solver. It reads PumpProperties and returns beta advanced by one outer time step using the instantaneous one-dimensional z-traversal pump rate. For diagnostics, call oneDimensionalZTraversalPumpRate(...) directly to inspect the frozen-state contribution \(d\beta/dt\) that the solver uses.

BetaIntegrationGaussianSolver is the legacy/default super-Gaussian pump solver. BetaIntegrationSolver and BetaInt3PumpSolver are compatibility aliases for the same solver. The lower-level helpers integrateLaserPump and runLaserPumpStep remain available for workflows that need the historical analytical pump update directly.

Physical Constants

Constants stores predefined physical constants. Simulation creates this object automatically, so most users do not need to pass constants explicitly.

from HASEonGPU import Constants

constants = Constants()
constants.speedOfLight
constants.planckConstant

These correspond to \(c\) and \(h\) in the pump equations.

The short names used by the low-level pump routine remain available as aliases:

constants.c
constants.h
constants.toDict()
constants.describeConstant("speedOfLight")

Backend Names

AlpakaBackends can list backend names discovered from the installed HASEonGPU backend-name library. Use these strings wherever the Python interface accepts a backend option, for example in PhiASE or the low-level calcPhiASE(...) call:

from HASEonGPU import AlpakaBackends, PhiASE

available = AlpakaBackends.all()
backend = available[0]

phi_ase = PhiASE(backend=backend)

AlpakaBackends.known() is an alias for AlpakaBackends.all(). Backend names that are valid Python identifiers are also exposed as class attributes, for example AlpakaBackends.Host_Cpu_CpuSerial.

For details on how the helper library is built and how backend names are formed, see Backend Selection.