def integrate( state: NDArray[(Any, 3), float], magnitude_spin_moment: NDArray[Any, float], temperature: NDArray[Any, float], damping: float, deltat: float, gyromagnetic: float, kB: float, magnetic_fields: NDArray[(Any, 3), float], exchanges: NDArray[(Any, Any), float], neighbors: NDArray[(Any, Any), float], anisotropy_constants: NDArray[Any, float], anisotropy_vectors: NDArray[(Any, 3), float], ) -> float: # compute external fields. These fields does not change # because they don't depend on the state Hext = thermal_field(temperature, magnitude_spin_moment, damping, deltat, gyromagnetic, kB) Hext += magnetic_field(magnetic_fields) # predictor step # compute the effective field as the sum of external fields and # spin fields Heff = Hext + exchange_interaction_field(state, magnitude_spin_moment, exchanges, neighbors) Heff = Heff + anisotropy_interaction_field( state, magnitude_spin_moment, anisotropy_constants, anisotropy_vectors) # compute dS based on the LLG equation dS = dS_llg(state, Heff, damping, gyromagnetic) # compute the state_prime state_prime = state + deltat * dS # normalize state_prime state_prime = normalize(state_prime) # corrector step # compute the effective field prime by using the state_prime. We # use the Heff variable for this in order to reutilize the memory. Heff = Hext + exchange_interaction_field( state_prime, magnitude_spin_moment, exchanges, neighbors) Heff = Heff + anisotropy_interaction_field( state_prime, magnitude_spin_moment, anisotropy_constants, anisotropy_vectors) # compute dS_prime employing the Heff prime and the state_prime dS_prime = dS_llg(state_prime, Heff, damping, gyromagnetic) # compute the new state integrate = state + 0.5 * (dS + dS_prime) * deltat # normalize the new state return normalize(integrate)
def test_exchange_interaction_field_null_J_exchange(random_state_spins, build_sample): num_sites, num_interactions, neighbors, num_neighbors = build_sample spin_moments = numpy.ones(shape=num_sites) j_exchange = numpy.zeros(shape=num_interactions) exchanges = j_exchange.reshape(num_sites, 6) neighbors_ = numpy.array(neighbors).reshape(num_sites, 6) expected = numpy.zeros(shape=(num_sites, 3)) total = spin_fields.exchange_interaction_field( random_state_spins, spin_moments, exchanges, neighbors_ ) assert numpy.allclose(expected, total)
def test_exchange_interaction_field_null_magnetic_moments( random_state_spins, build_sample, random_j_exchange ): num_sites, _, neighbors, _ = build_sample exchanges = random_j_exchange.reshape(num_sites, 6) neighbors_ = numpy.array(neighbors).reshape(num_sites, 6) null_moments = numpy.array([0.0] * num_sites) expected = numpy.full((num_sites, 3), numpy.inf) total = numpy.abs( spin_fields.exchange_interaction_field( random_state_spins, null_moments, exchanges, neighbors_ ) ) assert numpy.allclose(total, expected)
def test_exchange_interaction_field_constant_J_exchange( random_state_spins, build_sample ): num_sites, num_interactions, neighbors, num_neighbors = build_sample spin_moments = numpy.ones(shape=num_sites) j_exchange = numpy.full(num_interactions, numpy.random.uniform(-10, 10)) exchanges = j_exchange.reshape(num_sites, 6) neighbors_ = numpy.array(neighbors).reshape(num_sites, 6) expected = compute_exchange_field( num_sites, random_state_spins, j_exchange, spin_moments, num_neighbors, neighbors, ) assert numpy.allclose( spin_fields.exchange_interaction_field( random_state_spins, spin_moments, exchanges, neighbors_ ), expected, )
def test_exchange_interaction_field_random_spin_moments( random_state_spins, build_sample, random_spin_moments, random_j_exchange ): num_sites, _, neighbors, num_neighbors = build_sample exchanges = random_j_exchange.reshape(num_sites, 6) neighbors_ = numpy.array(neighbors).reshape(num_sites, 6) expected = compute_exchange_field( num_sites, random_state_spins, random_j_exchange, random_spin_moments, num_neighbors, neighbors, ) assert numpy.allclose( spin_fields.exchange_interaction_field( random_state_spins, random_spin_moments, exchanges, neighbors_, ), expected, )