Relaxers
- class pfc_util.StressRelaxer(field: RealField2D, dt: floating | float64 | float, eps: floating | float64 | float, mu: floating | float64 | float, *, expansion_rate: floating | float64 | float = 1.0, resize_cycle: int = 31)
Bases:
StressRelaxerBase,MinimizerMixin,MuMinimizerMixinConstant chemical potential stress relaxer
Equations of motion:
\[\dot\psi = -\frac{\delta\Omega}{\delta\psi}\]\[\dot L_x = -\eta V\frac{\partial\omega}{\partial L_x}\]\[\dot L_y = -\eta V\frac{\partial\omega}{\partial L_y}\]- __init__(field: RealField2D, dt: floating | float64 | float, eps: floating | float64 | float, mu: floating | float64 | float, *, expansion_rate: floating | float64 | float = 1.0, resize_cycle: int = 31)
- Parameters:
field – the PFC field to be minimized
dt – time step
eps – PFC \(\epsilon\)
mu – chemical potential \(\mu\)
expansion_rate – coefficient parametrizing the speed of expansion (\(\eta\))
resize_cycle – period (in number of time steps) of field resizing
- on_size_changed()
This method is called immediately after relax_stress() or resize_field() Its purpose is to update variables that depend on the system size such as Kx, Ky, K2 etc
- get_realspace_steps() List[Callable[[float], None]]
Return a list of steps to be run during
step()
- step_kernel(dt: float)
Minimization for linear terms This method is called twice during step(): Once before relax_stress() and once after. Both are invoked with self.dt/2
- update_domega_kernels()
This method is called immediately before relax_stress(). The purpose is to calculate the derivatives of mean grand potential density w.r.t to system size.
self._domega_kernels should be updated here.
- start() None
A hook method that is called before evolution When overriden, super().start() should be invoked
- class pfc_util.StressRelaxerBase(field: RealField2D, dt: floating | float64 | float, *, expansion_rate: floating | float64 | float = 1.0, resize_cycle: int = 31)
Bases:
SplitStep[RealField2D]Abstract base class for stress relaxers.
This minimizer follows the following procedure to find the field values and size that minimizes the mean grand potential density:
x scale, y scale = (1, 1)
Lx, Ly = field.Lx, field.Ly
update field values & x, y scales by dt \(Q>=1\) times
(resize) field.Lx, field.Ly *= scales
x scale, y scale = (1, 1)
repeat 3,4,5
Subclasses must implement:
get_realspace_steps()
step_kernel()
on_size_changed()
update_domega_kernels()
- __init__(field: RealField2D, dt: floating | float64 | float, *, expansion_rate: floating | float64 | float = 1.0, resize_cycle: int = 31)
- Parameters:
expansion_rate:
- Lx
self.Lx is equivalent to field.Lx * self.fx
- Ly
self.Ly is equivalent to field.Ly * self.fy
- NN
Number of points in the field, used for convolution
- start() None
A hook method that is called before evolution When overriden, super().start() should be invoked
- step()
Run a single minimization step.
- abstract step_kernel(dt: floating | float64 | float)
Minimization for linear terms This method is called twice during step(): Once before relax_stress() and once after. Both are invoked with self.dt/2
- abstract update_domega_kernels()
This method is called immediately before relax_stress(). The purpose is to calculate the derivatives of mean grand potential density w.r.t to system size.
self._domega_kernels should be updated here.
- property grid: T_grid
An alias for .subject
- initialize_fft(*, reinit: bool = True, threads: int = 1, planning_timelimit: float | None = None, effort: Literal['FFTW_ESTIMATE', 'FFTW_MEASURE', 'FFTW_PATIENT', 'FFTW_EXHAUSTIVE'] | None = None, wisdom_only: bool = False, destroy_input: bool = False, unaligned: bool = False)
Call .grid.initialize_fft() with the same arguments
- abstract on_size_changed()
This method is called immediately after relax_stress() or resize_field() Its purpose is to update variables that depend on the system size such as Kx, Ky, K2 etc
- resolve_hooks(hooks: EvolverHooks | None) EvolverHooks
Each Evolver instance is also an instance of EvolverHooks. By default none of the hook methods are implemented.
- run(n_steps: int, hooks: EvolverHooks | None = None)
Run evolution loop. hooks.on_nonstop_step() will be called every [n_steps] steps. The minimization will be run on a separate thread.
- run_multisteps(n_steps: int, n_epochs: int, hooks: EvolverHooks | None = None)
Run evolution loop
- run_steps(n_steps: int)
Run [n_steps] minimization steps.
- wait()
Wait till the evolution thread ends
- data: Dict[str, Any]
Used to store fields used by hooks, will be cleared everytime start() is called. I.e., before every evolution.
- relax_stress(dt: floating | float64 | float)
Stress-relaxing. This method should update self.fx and self.fy (scale factors). The default behavior is to use self._domega_kernels to compute dfx and dfy
- resize_field()
This method is called every [Q==resize_cycle] steps. The field is resized to Lx==Lx0*fx, Ly==Ly0*fy, and (fx, fy) are reset to (1, 1).
- final real_convolution_2d(psi_k_sq: ndarray[Any, dtype[float64]], kernel: ndarray[Any, dtype[float64]]) ndarray[Any, dtype[float64]]
Given \(|\psi_k^2|\) where \(\psi_k \; (Nx, Ny/2+1)\) is the real Fourier transform of real field \(\psi \; (Nx, Ny)\), calculate the inner product \(\braket{\psi K \psi}\) where K = kernel.
The kernel K is given as an array of shape (Nx, Ny/2+1) in the k space.