pyphasefield package — pyphasefield documentation

# pyphasefield package

## Subpackages

- pyphasefield.Engines package
  - Submodules
  - pyphasefield.Engines.AnisoDorrGPU module
    - `AnisoDorrGPU`
      - `AnisoDorrGPU.init_fields()`
      - `AnisoDorrGPU.init_tdb_params()`
      - `AnisoDorrGPU.just_before_simulating()`
      - `AnisoDorrGPU.simulation_loop()`
    - `AnisoDorr_helper_kernel()`
    - `AnisoDorr_kernel()`
    - `divagradb()`
    - `engine_AnisoDorrGPU()`
    - `f_ori_term()`
    - `get_thermodynamics()`
    - `grad2()`
    - `init_AnisoDorrGPU()`
    - `make_seed()`
  - pyphasefield.Engines.CahnAllen module
    - `CahnAllen`
      - `CahnAllen.init_fields()`
      - `CahnAllen.just_before_simulating()`
      - `CahnAllen.simulation_loop()`
    - `engine_CahnAllenCrankNicolson2D_ADI()`
    - `engine_CahnAllenExplicit()`
    - `engine_CahnAllenIMEX1D()`
    - `engine_CahnAllenImplicit1D()`
    - `engine_CahnAllenImplicit1D_GMRES()`
    - `engine_CahnAllenImplicit2D_ADI()`
    - `engine_CahnAllenImplicit2D_ADI_GMRES()`
    - `engine_CahnAllenImplicit2D_GMRES()`
    - `engine_CahnAllenImplicit3D_ADI()`
    - `functional_CahnAllen()`
    - `implicit_matrix_1d()`
    - `implicit_matrix_2d()`
  - pyphasefield.Engines.CahnHilliard module
    - `CahnHilliard`
      - `CahnHilliard.init_fields()`
      - `CahnHilliard.just_before_simulating()`
      - `CahnHilliard.simulation_loop()`
    - `engine_CahnHilliardCrankNicolson1D()`
    - `engine_CahnHilliardCrankNicolson1D_GMRES()`
    - `engine_CahnHilliardCrankNicolson2D_ADI()`
    - `engine_CahnHilliardExplicit()`
    - `engine_CahnHilliardIMEX1D()`
    - `engine_CahnHilliardImplicit1D()`
    - `engine_CahnHilliardImplicit1D_GMRES()`
    - `engine_CahnHilliardImplicit2D_ADI()`
    - `engine_CahnHilliardImplicit2D_ADI_GMRES()`
    - `engine_CahnHilliardImplicit2D_GMRES()`
    - `engine_CahnHilliardImplicit3D_ADI()`
    - `functional_CahnHilliard()`
    - `implicit_matrix_1d()`
    - `implicit_matrix_2d()`
  - pyphasefield.Engines.Diffusion module
    - `Diffusion`
      - `Diffusion.init_fields()`
      - `Diffusion.just_before_simulating()`
      - `Diffusion.simulation_loop()`
    - `diffusion_kernel_1D()`
    - `diffusion_kernel_2D()`
    - `diffusion_kernel_3D()`
    - `diffusion_matrix_1d()`
    - `diffusion_matrix_2d()`
    - `diffusion_matrix_3d()`
    - `engine_CrankNicolsonDiffusion1D()`
    - `engine_CrankNicolsonDiffusion1D_GMRES()`
    - `engine_CrankNicolsonDiffusion2D()`
    - `engine_CrankNicolsonDiffusion2D_ADI()`
    - `engine_CrankNicolsonDiffusion2D_ADI_GMRES()`
    - `engine_CrankNicolsonDiffusion2D_GMRES()`
    - `engine_CrankNicolsonDiffusion3D()`
    - `engine_CrankNicolsonDiffusion3D_ADI()`
    - `engine_CrankNicolsonDiffusion3D_ADI_GMRES()`
    - `engine_CrankNicolsonDiffusion3D_GMRES()`
    - `engine_DiffusionGPU()`
    - `engine_ExplicitDiffusion()`
    - `engine_ImplicitDiffusion1D()`
    - `engine_ImplicitDiffusion1D_GMRES()`
    - `engine_ImplicitDiffusion2D()`
    - `engine_ImplicitDiffusion2D_ADI()`
    - `engine_ImplicitDiffusion2D_ADI_GMRES()`
    - `engine_ImplicitDiffusion2D_GMRES()`
    - `engine_ImplicitDiffusion3D()`
    - `engine_ImplicitDiffusion3D_ADI()`
    - `engine_ImplicitDiffusion3D_ADI_GMRES()`
    - `engine_ImplicitDiffusion3D_GMRES()`
  - pyphasefield.Engines.DiffusionGPU module
  - pyphasefield.Engines.NCGPU module
    - `NCGPU`
      - `NCGPU.init_fields()`
      - `NCGPU.init_tdb_params()`
      - `NCGPU.just_before_simulating()`
      - `NCGPU.simulation_loop()`
    - `NComponent_helper_kernel()`
    - `NComponent_kernel()`
    - `NComponent_noise_kernel()`
    - `divagradb()`
    - `f_ori_term()`
    - `get_thermodynamics()`
    - `make_seed()`
    - `npvalue()`
  - pyphasefield.Engines.NCGPU_new module
    - `NCGPU_new`
      - `NCGPU_new.init_fields()`
      - `NCGPU_new.init_tdb_params()`
      - `NCGPU_new.just_before_simulating()`
      - `NCGPU_new.save_simulation()`
      - `NCGPU_new.simulation_loop()`
    - `NComponent_helper_kernel_2D()`
    - `NComponent_helper_kernel_3D()`
    - `NComponent_kernel_2D()`
    - `NComponent_kernel_3D()`
    - `NComponent_noise_kernel_2D()`
    - `NComponent_noise_kernel_3D()`
    - `NComponent_sp_kernel_2D()`
    - `NComponent_sp_kernel_3D()`
    - `divagradb()`
    - `divagradb_3D()`
    - `f_ori_term()`
    - `f_ori_term_3D()`
    - `get_thermodynamics()`
    - `npvalue()`
  - pyphasefield.Engines.NComponent module
    - `add_nuclei()`
    - `compute_tdb_energy_nc()`
    - `compute_tdb_energy_nc_rev()`
    - `discretization_NComponent()`
    - `divagradb()`
    - `engine_NComponent_ADI()`
    - `engine_NComponent_AnisoM()`
    - `engine_NComponent_Explicit()`
    - `engine_NComponent_FrozenOrientation()`
    - `engine_params_NComponent()`
    - `find_Pn()`
    - `functional_NComponent()`
    - `gaq()`
    - `grad2()`
    - `grad_c()`
    - `grad_l()`
    - `grad_r()`
    - `init_NComponent()`
    - `init_tdb_parameters()`
    - `make_seed()`
    - `npvalue()`
    - `quaternion_implicit_matrix()`
    - `quaternion_implicit_method()`
    - `renormalize()`
  - pyphasefield.Engines.Template module
    - `Template`
      - `Template.init_fields()`
      - `Template.init_tdb_params()`
      - `Template.just_before_simulating()`
      - `Template.simulation_loop()`
  - pyphasefield.Engines.Warren1995 module
    - `Warren1995`
      - `Warren1995.init_fields()`
      - `Warren1995.just_before_simulating()`
      - `Warren1995.simulation_loop()`
    - `Warren1995_helper_kernel()`
    - `Warren1995_kernel()`
    - `engine_Warren1995()`
    - `gradx()`
    - `gradxx()`
    - `grady()`
    - `gradyy()`
    - `init_Warren1995()`
  - Module contents
- pyphasefield.tests package
  - Submodules
  - pyphasefield.tests.test_Diffusion module
    - `test_diffusion_CrankNicolson1D()`
    - `test_diffusion_CrankNicolson1D_GMRES()`
    - `test_diffusion_CrankNicolson2D()`
    - `test_diffusion_CrankNicolson2D_ADI()`
    - `test_diffusion_CrankNicolson2D_ADI_GMRES()`
    - `test_diffusion_CrankNicolson2D_GMRES()`
    - `test_diffusion_CrankNicolson3D()`
    - `test_diffusion_CrankNicolson3D_ADI()`
    - `test_diffusion_CrankNicolson3D_ADI_GMRES()`
    - `test_diffusion_CrankNicolson3D_GMRES()`
    - `test_diffusion_Implicit1D()`
    - `test_diffusion_Implicit1D_GMRES()`
    - `test_diffusion_Implicit2D()`
    - `test_diffusion_Implicit2D_ADI()`
    - `test_diffusion_Implicit2D_ADI_GMRES()`
    - `test_diffusion_Implicit2D_GMRES()`
    - `test_diffusion_Implicit3D()`
    - `test_diffusion_Implicit3D_ADI()`
    - `test_diffusion_Implicit3D_ADI_GMRES()`
    - `test_diffusion_Implicit3D_GMRES()`
    - `test_diffusion_default1dexplicit()`
    - `test_diffusion_default2dexplicit()`
    - `test_diffusion_default3dexplicit()`
  - pyphasefield.tests.test_NComponent module
    - `test_ncomponent()`
    - `test_ncomponent_1d()`
    - `test_ncomponent_1d_actual()`
    - `test_ncomponent_very_small()`
  - pyphasefield.tests.test_SaveLoad module
    - `teardown_module()`
    - `test_1_saving()`
    - `test_2_loading_step_number()`
    - `test_3_loading_relative_path()`
    - `test_4_loading_absolute_path()`
  - pyphasefield.tests.test_Warren1995 module
    - `test_warren1995()`
  - Module contents

## Submodules

## pyphasefield.field module

class pyphasefield.field.Field(data=None, simulation=None, name=None, full_grid=False, boundary_field=None, colormap='GnBu')

  Bases: `object`

  The Field class, which stores data related to one field in the overall simulation

  data

    the full array of data in the field, including boundary condition cells use the method Field.get_cells() to just get the non-boundary data

    Type:

      ndarray

  name

    Name of the field, for use in plotting images and the like

    Type:

      str

  colormap

    The colormap to be used for plotting images

    Type:

      Matplotlib formatted Colormap

  for reference, private attributes are included below
  _simulation

    pointer back to the Simulation instance

    Type:

      Simulation

  _slice

    internally used method for getting the non-boundary cells of the Field

    Type:

      Slice object

  _neighbors

    Used exclusively for parallel simulations A list containing 2*D values, D being the number of dimensions of the simulation The order for the list is [d0_left, d0_right, d1_left, d1_right, d2_left, d2_right] d0, d1, d2 correspond to the first, second, and third dimensions of the simulation (C-ordering! z then y then x) Left and right correspond to the boundary at index 0, and the boundary at index (len(dimension)-1) Values in the list of 0 or larger correspond to a boundary condition with the given MPI rank Value of -1 corresponds to Neumann boundary conditions Value of -2 corresponds to Dirichlet boundary conditions

    Type:

      list of int

  _slice_sbc_in

    Used exclusively for parallel simulations A list of 2*D slices, corresponding to the boundary condition cells specified in the _neighbors list

    Type:

      list of Slice objects

  _slice_sbc_out

    Used exclusively for parallel simulations Only used for MPI boundaries, these slices correspond to the data that will be sent to neighboring MPI subgrids

    Type:

      list of Slice objects

  _transfer_in

    Used exclusively for parallel simulations A list of D ndarrays, which are contiguous 1D arrays used for the Send and Recv numpy array functions in mpi4py Each dimension can be a different size, each have as many cells as the two corresponding _slice_sbc_in Slice objects These are arrays reserved for receiving data from neighboring MPI subgrids

    Type:

      list of ndarray

  _transfer_out

    Used exclusively for parallel simulations A list of D ndarrays, which are contiguous 1D arrays used for the Send and Recv numpy array functions in mpi4py Each dimension can be a different size, each have as many cells as the two corresponding _slice_sbc_out Slice objects These are arrays reserved for sending data to neighboring MPI subgrids

    Type:

      list of ndarray

  _shapes

    Corresponds to the shape of the _slice_sbc_in (and out) Slice object for each dimension Used for reshaping the 1D flattened transfer arrays back to the “correct” shape in the boundary condition cells of the Field

    Type:

      list of tuple

  get_all_cells()
  get_cells()
  gradient_cell()
  gradient_face_left()
  gradient_face_right()
  laplacian()

## pyphasefield.ppf_gpu_utils module

pyphasefield.ppf_gpu_utils.apply_boundary_conditions(sim)

pyphasefield.ppf_gpu_utils.apply_parallel_bcs(sim)

pyphasefield.ppf_gpu_utils.boundary_kernel_1D_single_x(field, bcfield, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.boundary_kernel_1D_x(fields, bcfields, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.boundary_kernel_2D_single_x(field, bcfield, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.boundary_kernel_2D_single_y(field, bcfield, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.boundary_kernel_2D_x(fields, bcfields, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.boundary_kernel_2D_y(fields, bcfields, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.boundary_kernel_3D_single_x(field, bcfield, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.boundary_kernel_3D_single_y(field, bcfield, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.boundary_kernel_3D_single_z(field, bcfield, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.boundary_kernel_3D_x(fields, bcfields, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.boundary_kernel_3D_y(fields, bcfields, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.boundary_kernel_3D_z(fields, bcfields, bcs, l, r, dx)

pyphasefield.ppf_gpu_utils.clean_GPU(sim)

pyphasefield.ppf_gpu_utils.create_GPU_devices(sim)

pyphasefield.ppf_gpu_utils.retrieve_fields_from_GPU(sim)

pyphasefield.ppf_gpu_utils.retrieve_fields_from_GPU_minimal(sim)

pyphasefield.ppf_gpu_utils.send_fields_to_GPU(sim)

pyphasefield.ppf_gpu_utils.send_fields_to_GPU_minimal(sim)

pyphasefield.ppf_gpu_utils.update_temperature_field(sim)

pyphasefield.ppf_gpu_utils.update_thermal_file_1D_kernel(T, T0, T1, start, end, current)

pyphasefield.ppf_gpu_utils.update_thermal_file_2D_kernel(T, T0, T1, start, end, current)

pyphasefield.ppf_gpu_utils.update_thermal_file_3D_kernel(T, T0, T1, start, end, current)

pyphasefield.ppf_gpu_utils.update_thermal_gradient_1D_kernel(T, dTdt, dt)

pyphasefield.ppf_gpu_utils.update_thermal_gradient_2D_kernel(T, dTdt, dt)

pyphasefield.ppf_gpu_utils.update_thermal_gradient_3D_kernel(T, dTdt, dt)

## pyphasefield.ppf_utils module

pyphasefield.ppf_utils.CSVtoXDMF(csv_path, T_cutoffs=False, starting_T=None, ending_T=None, reflect_X=False)

class pyphasefield.ppf_utils.TDBContainer(tdb_path, phases=None, components=None)

  Bases: `object`

pyphasefield.ppf_utils.TSVtoHDF5(tsv_folder_path, files=None, times=None, file_t_units='us', target_t_units='s', file_x_units='cm', target_x_units='cm', cutoff_x=[-inf, inf], cutoff_y=[-inf, inf], cutoff_z=[-inf, 1e-05], relative_t=False)

class pyphasefield.ppf_utils.XDMFLoader(t_file_path)

  Bases: `object`

  data(step)

pyphasefield.ppf_utils.create_numba_ufunc_from_sympy(sp_ufunc)

  Converts sympy ufunc to numba

pyphasefield.ppf_utils.create_sympy_ufunc_from_tdb(tdb, phase, components, mode)

  Creates a sympy ufunc from the given phase/components of the tdb

pyphasefield.ppf_utils.make_seed(sim, p=0, q=[1, 2, 3, 4], c=[5], composition=None, x=None, y=None, z=None, angle=None, axis=[0, 0, 1], orientation=None, seed_radius=5, q_extra=5)

  Fairly comprehensive method for adding seed nuclei to a simulation

  Parameters:

    - sim (pyphasefield.Simulation) – The simulation to add a seed nuclei to

    - p (int, default = 0) – Index of the order field (“phi”)

    - q (list of int, default = [1, 2, 3, 4]) – Indices of the quaternion orientation fields Either 0, 2, or 4 long. 0 means no quaternions, 2 is 2D, equivalent to complex rotation, 4 is 3D, full quaternion orientation

    - c (list of int, default = [5]) – Indices of the composition fields

    - composition (list of float, default = None) – A list containing the values to set the composition field equal to If None, do not set the composition field at all (order-parameter only nucleation) If defined, must be the same length as c!

    - x (int, optional) – Cell index on x axis to center the seed nuclei. If unspecified, choose a random location

    - y (int, optional) – Cell index on y axis to center the seed nuclei. If unspecified, choose a random location

    - z (int, optional) – Cell index on z axis to center the seed nuclei. If unspecified, choose a random location

    - angle (float, optional) – Angle to rotate about the z-axis (2D) or about the defined axis (3D). If unspecified in 2D, use a random rotation Used by default in 2D, or if orientation is not specified and angle is specified in 3D

    - axis (list of float, default = [0, 0, 1]) – Axis about which to rotate in 3D. Will be normalized automatically.

    - orientation (list of float, optional) – Quaternion orientation to be used in 3D. If neither this nor angle is specified in 3D, use a random orientation

    - seed_radius (int, default = 5) – Radius of the seed nuclei in the order field, in cells.

    - q_extra (int, default = 5) – seed_radius+q_extra is the radius of the seed nuclei in the orientation fields (to ensure the nuclei grows in a bubble of defined orientation until the quaternion evolution equations take over)

  Notes

  This function will account for parallelism (global vs. local coordinates) automatically.

pyphasefield.ppf_utils.make_seed_masks(r, q_extra, ndims)

pyphasefield.ppf_utils.random_uniform_quaternion()

pyphasefield.ppf_utils.successfully_imported_numba()

  Checks if numba/cuda is installed. If not, warns the user that gpu-dependent features cannot be used Also tells the user how to install it (if the user has Anaconda)

pyphasefield.ppf_utils.successfully_imported_pycalphad()

  Checks if pycalphad is installed. If not, warns the user that pycalphad-dependent features cannot be used Also tells the user how to install it (if the user has Anaconda)

## pyphasefield.simulation module

class pyphasefield.simulation.Simulation(dimensions, framework=None, dx=None, dt=None, initial_time_step=0, temperature_type=None, initial_T=None, dTdx=0, dTdy=0, dTdz=0, dTdt=0, temperature_path=None, temperature_units='K', tdb_container=None, tdb_path=None, tdb_components=None, tdb_phases=None, save_path=None, autosave=False, save_images=False, autosave_rate=None, boundary_conditions=None, user_data={})

  Bases: `object`

  Class used by pyphasefield to store data related to a given simulation

  _framework

    A string which defines in what computational framework the simulation will run, as implemented in the Engine Values can be CPU_SERIAL, CPU_PARALLEL, GPU_SERIAL, or GPU_PARALLEL (SERIAL implies a single device (no MPI communication), PARALLEL implies multiple devices, where MPI is required) (CPU runs like normal python code, GPU runs on the GPU using numba/CUDA integration, requiring numba and cudatoolkit)

    Type:

      str

  _gpu_blocks_per_grid_1D

    Defines the number of blocks of threads that CUDA will use Similar private attributes exist for 2D/3D, of length 2 and 3, with defaults (16, 16) and (8, 8, 8), respectively For advanced usage, can be modified to change how many resources CUDA uses

    Type:

      tuple of int, length 1, default = (256)

  _gpu_threads_per_block_1D

    Defines the number of threads per block that CUDA will use Similar private attributes exist for 2D/3D, of length 2 and 3, with defaults (16, 16) and (8, 8, 8), respectively For advanced usage, can be modified to change how many resources CUDA uses

    Type:

      tuple of int, length 1, default = (256)

  fields

    The list containing the fields of the phase field model Arbitrary convention is that the order of the fields is phase(s), then orientation(s), then composition(s) e.g. for the NCGPU model, Simulation.fields[0] is phase,

    > Simulation.fields[1] and Simulation.fields[2] are the 2D quaternion orientation fields Simulation.fields[3] onwards are the composition fields, sorted in alphabetical order by element (CALPHAD convention)

    Type:

      list of Field

  dimensions

    defines the length, width (and possibly depth) of the simulation. Boundary conditions will be appended to these sizes as needed. e.g. Submitting dimensions of [100, 100], with default boundary conditions of one cell in width,

    > will have an overall array size of [102, 102]. The “dimensions” attribute will remain [100, 100], however.

    Type:

      list of int

  dx

    dx is the cell spacing, the distance between neighboring cells, in arbitrary units (typically m or cm) This is the value used in finite difference equations, often specified as (delta)x in the math pyphasefield uses a structured square/cubic mesh, so this is used for all dimensions

    Type:

      float

  dt

    dt is the time step, the length of time between simulation states, in units of seconds This is the value used in finite difference equations, often specified as (delta)t in the math Some Engines may calculate a suitable value for dt automatically, using a variation of the Courant condition

    Type:

      float

  time_step_counter

    Specifies the count of how many time steps have passed in the simulation when the simulation is initialized Defaults to zero (assumes a new simulation, where zero time steps have passed yet) This parameter affects the index used for save files, and the initial value of the frozen gradient thermal field

    Type:

      int, default = 0

  temperature

    A Field containing the value of the temperature field at every cell in the simulation (This field will have the same value everywhere if Simulation._temperature_type == “ISOTHERMAL”) Defined separately from the other fields, as certain standard temperature types could work for any simulation

    Type:

      Field

  _temperature_type

    A string which defines the method used for the temperature field Values can be ISOTHERMAL, LINEAR_GRADIENT, or THERMAL_HISTORY_FILE ISOTHERMAL: Single, static temperature FROZEN_GRADIENT: Static (“frozen”) thermal gradient, thermal field is not evolved like the other fields ACTIVE_GRADIENT: Dynamic thermal gradient, thermal field must be simulated just like the other fields THERMAL_HISTORY_FILE: Static temperature field

    > defined by a HDF5 file using h5py or by a XDMF file using meshio.xdmf.TimeSeriesReader linearly interpolates between defined thermal slices, as it is impractical to store thermal data for every PF time step

    (Here, static means the temperature field is not simulated by phase field equations, it is an independent variable) If undefined, the simulation will not use/initialize a temperature field

    Type:

      str, optional

  _temperature_path

    If Simulation._temperature_type == “THERMAL_HISTORY_FILE”, the thermal history will be read from the file at this path REQUIRED if Simulation._temperature_type == “THERMAL_HISTORY_FILE”

    Type:

      str, optional

  _temperature_units

    NOTE: pyphasefield always uses kelvin under the hood! This variable is only used for plotting graphs

    Type:

      str, default = “K”

  _initial_T

    Defines the initial temperature of the simulation, in the corner where array indices are 0, at time step 0, in units of K (Specifying the corner is important, because values will change from there in the LINEAR_GRADIENT case) REQUIRED if Simulation._temperature_type == “ISOTHERMAL” or Simulation._temperature_type == “LINEAR_GRADIENT”

    Type:

      float, optional

  _dTdx

    Specifies the slope of the thermal gradient in the x-direction, in units of K/m or K/cm, depending on the units of dx similar attributes exist for the y and z directions

    Type:

      float, default = 0

  _dTdt

    Specifies how the thermal field will change with time, in units of K/s IMPORTANT: typically phase field solidification simulations will demand cooling to model liquid -> solid, and

    > cooling is a negative value for dTdt!

    Type:

      float, default = 0

  _tdb_container

    A class which stores the phases, components, and codegen functions for a particular tdb file Large TDB files can have large overheads for loading (> 1min), this class ensures the process needs only happen once This can be useful for running multiple simulations in series using the same TDB file

    Type:

      TDBContainer

  _tdb_path

    Alternate way to define the .tdb file used, pycalphad will load the database at this path if _tdb_container is undefined

    Type:

      str

  _tdb_components

    Defines the components of the .tdb file which will be used in the simulation e.g. if the .tdb file is a Al-Cu-Ni database, specifying [“CU”, “NI”] will only use the binary Cu-Ni portion of the database If undefined, all components of the .tdb file are used in the simulation

    Type:

      list of str, optional

  _tdb_phases
    Defines the phases of the .tdb file which will be used in the simulation
      e.g. if the .tdb file is a database containing the LIQUID, FCC_A1, and BCC_A2 phases, specifying [“FCC_A1”, “LIQUID”]

        will only use those two phases from the database

    If undefined, all phases in the .tdb file are used in the simulation

    Type:

      list of str, optional

  _save_path

    Path where output files, checkpoints, etc. will be saved from the simulation

    Type:

      str

  _autosave_flag

    If true, checkpoints will automatically be saved

    Type:

      Bool, default = False

  _autosave_rate

    If Simulation._autosave_flag is True, checkpoints will be saved every time this many time steps pass

    Type:

      int

  _autosave_save_images_flag

    If true, also save images of the fields whenever the autosave function happens

    Type:

      Bool, default = False

  boundary_fields

    list equal in length to fields, containing a complementary set of fields representing the boundary conditions Defaults to zero, Dirichlet bcs will therefore impose a value of zero, Neumann bcs will impose a slope of zero Only uses values at the border of the array (convenience). Inefficient, but manageable especially with parallelism

    Type:

      list of Field

  _boundary_conditions_type
    String that defines the boundary conditions in every dimension, or list that defines the boundary conditions

      in each dimension separately (length of list == number of dimensions), or list that defines the boundary conditions separately in each dimension and each side of the domain (length of list == 2*number of dimensions)

    Options for values for string(s): PERIODIC, NEUMANN, or DIRICHLET, described conceptually as follows PERIODIC: boundary value on left edge = value on right edge NEUMANN: boundary value on left edge and value on left edge have slope defined by Simulation.boundary_fields DIRICHLET: boundary value on left edge has value equal to that in Simulation.boundary_fields Will be automatically converted into the list of size 2*number of dimensions when set through set_boundary_conditions!

    > DON’T set this directly!

    Type:

      str OR list of str

  _neighbors

    Set based on _boundary_conditions_type when using Simulation.set_boundary_conditions Specifically useful for parallelism (which core is the “periodic” boundary condition?) and GPUs (GPUs can’t handle str)

    Type:

      list of int

  user_data

    Arbitrary dictionary of parameters for the specific subclass engine e.g. Diffusion has the following params in the dict:

    > Dfloat

    >   the diffusivity used in the simulation

    > solverstr

    >   “explicit”, “implicit”, or “crank-nicolson”, the method for solving the finite difference equation

    > adiBool

    >   for True, use the alternating direction implicit method for fast computation, if 2D/3D

    > gmresBool

    >   for True, use the gmres approximation method (implemented in scipy) for the implicit matrix equations

    Type:

      dict

  add_field(array, array_name, full_grid=False, colormap='GnBu')

    Creates a Field from a numpy array, and adds it to the Simulation instance Also adds a complementary boundary condition field

    Parameters:

      - array (ndarray) – A numpy array containing the values for the field at every point. Don’t include boundary cells in this array, they will be added automatically

      - array_name (str) – A string naming the field, used for plotting graphs of the field

      - colormap (Matplotlib colormap, str, etc.. Default = "GnBu") – The colormap used for plotting the field. Defaults to a green blue sequential colormap

  apply_boundary_conditions(init=False)
  create_GPU_devices()
  default_value(key, value)

    One line helper function for setting default values in the user_data for a subclass

    If the value is already defined, this does nothing, otherwise sets the value of the corresponding key to a default value

    Parameters:

      - key (str) – Name of the key in the user_data dictionary

      - value (any) – Arbitrary value to be used as the default value of the previously specified key

  finish_simulation()
  generate_python_script()
  get_cell_spacing()

    See get_dx()

  get_dimensions()
  get_dt()
  get_dx()
  get_framework()
  get_time_step_counter()
  get_time_step_length()

    See get_dt()

  init_fields()

    Initializes the Field class instances for a given simulation. Deprecated, use the initialize_engine pathway instead!

    Notes

    Exclusively used by the subclass, base Simulation class does not initialize fields! This and initialize_fields_and_imported_data are both inherited by the subclass, with the second requiring

    > calling super.initialize_fields_and_imported_data()

    This function is meant to initialize the number (and potentially contents) of the field The second is meant for actions that must be taken after everything else is initialized (setting values in the boundary

    > condition array, as an example)

  init_sim_CahnAllen(dim=[200], solver='explicit', gmres=False, adi=False)
  init_sim_CahnHilliard(dim=[200], solver='explicit', gmres=False, adi=False)
  init_sim_Diffusion(dim=[200], solver='explicit', gmres=False, adi=False)
  init_sim_DiffusionGPU(dim=[200, 200], cuda_blocks=(16, 16), cuda_threads_per_block=(256, 1))
  init_sim_NCGPU(dim=[200, 200], sim_type='seed', number_of_seeds=1, tdb_path='Ni-Cu_Ideal.tdb', temperature_type='isothermal', initial_temperature=1574, temperature_gradient=0, cooling_rate=0, temperature_file_path='T.xdmf', initial_concentration_array=[0.40831], cell_spacing=4.6e-06, d_ratio=1.0638297872340425, solver='explicit', nbc=['periodic', 'periodic'], cuda_blocks=(16, 16), cuda_threads_per_block=(256, 1))
  init_sim_NComponent(dim=[200, 200], sim_type='seed', number_of_seeds=1, tdb_path='Ni-Cu_Ideal.tdb', temperature_type='isothermal', initial_temperature=1574, temperature_gradient=0, cooling_rate=0, temperature_file_path='T.xdmf', initial_concentration_array=[0.40831], cell_spacing=4.6e-06, d_ratio=1.0638297872340425, solver='explicit', nbc=['periodic', 'periodic'])
  init_sim_Warren1995(dim=[200, 200], diamond_size=15)
  init_tdb_params()

    Initializes the .tdb file, and associated codegen functions to compute the thermodynamics

    Notes

    The function will load from a given TDBContainer first. Only if one isn’t given, will it try and load from the tdb_path. Order of phases and compositions is always alphabetical. Can be overridden (call super.init_tdb_params() first!) to define model-specific TDB functionality

  init_temperature_field()

    Initializes the temperature Field

    Notes

    This function will automatically adjust the temperature based on Simulation.time_step_counter, as would be expected E.g. if you begin the simulation with Simulation.time_step_counter == 1000, that will have the same temperature field

    > as if you ran the simulation for 1000 timesteps, allowing the field to evolve with LINEAR_GRADIENT or XDMF_FILE

  initialize_engine()

    Function to initialize the simulation. Called after class attributes are set.

    Notes

    This function should be overridden by the subclass (calling super.initialize_engine() first!) Afterwards, the subclass version of this function should do all necessary initialization for the model e.g. Create Fields, set boundary condition array values, import additional required tdb variables, etc.

  initialize_fields_and_imported_data()

    Function to initialize the simulation, called after class attributes are set.

    Deprecated name, use initialize_engine() instead.

    Notes

    This and init_fields are both inherited by the subclass, with the first requiring

      calling super.initialize_fields_and_imported_data()

    This function is meant to initialize the number (and potentially contents) of the field The second is meant for actions that must be taken after everything else is initialized (setting values in the boundary

    > condition array, as an example)

  just_before_simulating()
  load_simulation(file_path=None, step=-1)

    Loads a simulation from a .npz file.

    Either a filename, step, or both must be provided. If no step is specified, checks filename for step #. If no filename is specified, a file with the specified step number is loaded from

    > the _save_path.

    Parameters:

      - file_path (str, optional) – Load the simulation from a different place than specified in Simulation._save_path

      - step (int, optional) – If a particular .npz file is not specified in file_path, load the file corresponding to this value E.g. step==100, would load /path/to/file/step_100.npz

  plot_all_fields()

    Plots each field in self.fields and saves them to the save_path in a separate dir Recommended for when the number of fields used would clutter the data folder

  plot_field(f, save_path=None)

    Plots each field as a matplotlib 2d image. Takes in a field object as arg and saves the image to the data folder as namePlot_step_n.png

  plot_simulation(fields=None, interpolation='bicubic', units='cells', save_images=False, show_images=True, size=None, norm=False)

    Plots/saves images of certain fields of the simulation

    Parameters:

      - fields (list of int, optional) – Plot the fields corresponding to the indices in this list. If unspecified, plot all fields

      - interpolation (str, default = "bicubic") – Matplotlib string corresponding to an interpolation scheme. Other options are “nearest”, “bilinear”, etc.

      - units (str, default = "cells") – Units for the plots. Can be “cells”, “m”, or “cm”. Plot assumes units for Simulation.dx are in m.

      - save_images (Bool, default = False) – If true, save .png images of the fields

      - show_images (Bool, default = True) – If true, plot images inline (jupyter notebook!)

      - size (list of int, optional) – If defined, plot images of the defined size (matplotlib convention, inches I believe…)

      - norm (Bool, default = False) – If true, plot the first field with a PowerNorm. Useful for seeing grain boundaries, as the first field is typically phase

  progress_bar()
  retrieve_fields_from_GPU()
  retrieve_fields_from_GPU_minimal()
  save_images(fields=None, interpolation='bicubic', units='cells', size=None, norm=False)
  save_simulation()

    Saves all fields in a .hdf5 in either the user-specified save path or a default path.

    Step number is saved in the file name. TODO: save data for simulation instance in header file

  send_fields_to_GPU()
  set_autosave_flag(autosave_flag)
  set_autosave_rate(autosave_rate)
  set_autosave_save_images_flag(autosave_save_images_flag)
  set_boundary_conditions(boundary_conditions_type)

    Sets self._boundary_conditions_type according to the input Produces a 2D list:

    > first axis is the number of dimensions of the simulation second axis has length 2, for left and right bcs

    Valid inputs (and resulting output in 3D):
      Single value: “PERIODIC”

        output: [[“PERIODIC”,”PERIODIC”],[“PERIODIC”,”PERIODIC”],[“PERIODIC”,”PERIODIC”]]

      One value per dim: [“PERIODIC”, “NEUMANN”, “DIRICHLET”]

        output: [[“PERIODIC”,”PERIODIC”],[“NEUMANN”,”NEUMANN”],[“DIRICHLET”,”DIRICHLET”]]

      Two values per dim: [“PERIODIC”, “NEUMANN”, “DIRICHLET”, “PERIODIC”, “NEUMANN”, “DIRICHLET”]

        output: [[“PERIODIC”,”NEUMANN”],[“DIRICHLET”,”PERIODIC”],[“NEUMANN”,”DIRICHLET”]]

      A 2D list: [[“PERIODIC”,”NEUMANN”],[“DIRICHLET”,”PERIODIC”],[“NEUMANN”,”DIRICHLET”]]

        outputs itself

  set_cell_spacing(dx)

    See set_dx()

  set_debug_mode_flag(debug_mode_flag)
  set_dimensions(dimensions)
  set_dt(dt)
  set_dx(dx)
  set_framework(framework)
  set_ghost_rows(rows)
  set_save_path(save_path)
  set_t_file_max(t_max)
  set_t_file_min(t_min)
  set_t_file_offset(offset_list)
  set_t_file_offset_cells(offset_list)
  set_t_file_offset_units(offset_list)
  set_tdb_components(tdb_components)
  set_tdb_container(tdb_container)
  set_tdb_path(tdb_path)
  set_tdb_phases(tdb_phases)
  set_temperature_dTdt(dTdt)
  set_temperature_dTdx(dTdx)
  set_temperature_dTdy(dTdy)
  set_temperature_dTdz(dTdz)
  set_temperature_initial_T(initial_T)
  set_temperature_path(temperature_path)
  set_temperature_type(temperature_type)
  set_temperature_units(temperature_units)
  set_time_step_counter(time_step_counter)
  set_time_step_length(dt)

    See set_dt()

  set_user_data(data)
  simulate(number_of_timesteps)

    Evolves the simulation for a specified number of timesteps

    Parameters:

      number_of_timesteps (int)

    Notes

    If the simulation has just been initialized, it will first call just_before_simulating(), which will deal with actions which

      only need to be taken once, like sending arrays to the GPU, applying boundary conditions for the first time, checking validity of data, etc.. Other actions may be taken by the individual subclass engines through inheriting the method.

  simulate_debug(number_of_timesteps)

    Evolves the simulation for a specified number of timesteps. Prints timing information

    Parameters:

      number_of_timesteps (int)

    Notes

    If the simulation has just been initialized, it will first call just_before_simulating(), which will deal with actions which

      only need to be taken once, like sending arrays to the GPU, applying boundary conditions for the first time, checking validity of data, etc.. Other actions may be taken by the individual subclass engines through inheriting the method.

  simulation_loop()

    This function will run once every time step. Override this in the subclass to put simulation code here!

  update_temperature_field(force_cpu=False)

## Module contents