Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create unit tests for the refactored spinwave calculation function #9

Open
krishnakumarg1984 opened this issue Feb 8, 2021 · 0 comments
Assignees
Labels
internal internal code changes
Projects

Comments

@krishnakumarg1984
Copy link
Contributor

krishnakumarg1984 commented Feb 8, 2021

Complete when there are unit tests that covers 80% of the core calculation code.

There should be several tests which checks the code flow within the spin_wave_calculator class dependent on input.

Object setup

For the tests, a very simple model should be used. I recommend using a linear spin chain with the spin magnitude set to 1 (e.g. like in tutorial 1:

model = spinw;
model.genlattice('lat_const', [3 8 8], 'angled', [90 90 90]);
model.addatom('r', [0 0 0],'S', 1, 'label', 'MCu1', 'color', 'blue');
model.gencoupling('maxDistance', 7);
model.addmatrix('value', -eye(3), 'label', 'Ja', 'color', 'green');
model.addcoupling('mat', 'Ja', 'bond', 1);
model.genmagstr('mode', 'direct', 'k', [0 0 0], 'n', [1 0 0], 'S', [0; 1; 0]);

This model has a particularly simple dispersion - a single mode with energy omega = 2*(1-cos(2*pi*qh)) (see Kittel, chapter 12, eq 22, but note that Kittel defines the Hamiltonian in eq 12 as -2Jsum_ij(Si.Sj) whereas in SpinW the prefactor of 2 is not included; also note that we've set the exchange integral to be 1 in the addmatrix command).

A non-Hermitian model can be setup by changing the magnetic structure to be antiferromagnetic instead:

model.genmagstr('mode', 'direct', 'nExt', [2 0 0], 'S', [0 0; 1 -1; 0 0]);

An incommensurate model can be setup by using the fourier mode and changing the k parameter:

k_incomm = 0.123;
model.genmagstr('mode', 'fourier', 'k', [k_incomm 0 0], 'n', [1 0 0], 'S', [0; 1; 0]);

Note that this would also give a non-Hermitian Hamiltonian because we have a ferromagnetic exchange interaction which would prefer all the spins to be parallel and this structure does not have that.

Possible tests

General tests for twins and incommensurate cases

  1. Test that twined input structures give cell arrays as output and number of cells match number of twins
  2. Test that incommensurate input structures give the correct number of output modes (6 times the number of atoms in the unit cell; a normal (commensurate) structures has 2*nMagExt number of modes, an incommensurate structure should have three times this, so 6*nMagExt number of modes)

More specific test for the twins case

For each twin, the user gives a 3x3 transformation matrix which is applied to the input hkl q-vectors. A test could do something like this:

  1. Run through the calculation with only a single hkl vector (pick any 3 values) -> orig_single output spectra
  2. Run the calculation again with the transformed rotmat * hkl vector -> transformed_single output spectra
  3. Run the calculation with the original hkl but with the twins set -> twinned output spectra
  4. Check the output omega field of the twinned output spectra is a cell with two elements (one for each twin, the first being the identity)
  5. Compare the first element of the output omega field of twinned with the omega of orig_single.
  6. Compare the second element of the output omega field of twinned with the omega of transformed_single.

Test for the form factor option

The magnetic form factor is a hkl-vector dependent scaling factor on the output neutron intensity. The test here would be to:

  1. Run the calculation with a range of hkl without the formfactor option set to false -> spec_no_ff
  2. Run the calculation with the formfactor option set to true -> spec_ff
  3. Compare spec_no_ff.swConv * ff and spec_ff.swConv.

Note, the swConv property is only generated after running sw_egrid(sw_neutron(spectra)).

Test that the correct calculation is run for the hermit option

There are two different matrix diagonalisation algorithms in SpinW - one which explicit requires a positive definite matrix which is used when hermit is true (that is, the Hamiltonian matrix must not be hermitian but its eigenvalues must also be strictly positive); and a second algorithm which works for any matrix but can give imaginary eigenvalues (e.g. unphysical spin wave energies) when the hermit option is set to false.

The test here is to define the input such that we are sure that Hamiltonian matrix would not be Hermitian and run the calculation with hermit set to true and check that it gives an error. Then run the test with hermit set to false and check that no error is thrown and that omega has imaginary values.

@mducle mducle added this to Backlog in SpinWCore Feb 8, 2021
@mducle mducle added the internal internal code changes label Mar 11, 2021
mducle added a commit that referenced this issue Apr 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internal internal code changes
Projects
SpinWCore
Backlog
Development

No branches or pull requests

2 participants