-
Notifications
You must be signed in to change notification settings - Fork 15
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
Test genmagstr #97
Test genmagstr #97
Conversation
In the if ~cmplxS... conditional any(k) returns a vector for multi-k structures, causing a MATLAB:nonLogicalConditional error, fix this by flattening k first
- Add test with multiple k and n - Add test with nSpin = nMagAtom - Add test with nSpin = nMagExt
Codecov Report
@@ Coverage Diff @@
## master #97 +/- ##
==========================================
- Coverage 26.40% 25.99% -0.42%
==========================================
Files 235 235
Lines 15690 15738 +48
==========================================
- Hits 4143 4091 -52
- Misses 11547 11647 +100
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
Test for number of magnetic atoms is already performed at beginning of function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this! It mostly looks good, but needs a few changes as you suggested in your main comments.
I didn't actually know that SpinW supported multi-k input in genmagstr
and looking at the code here I'm not sure that it's doing things correctly, as noted in the comments... but I think it would be good to merge these sets of tests so that we know what the code is doing now - we can then investigate the multi-k and non-unity k
and nExt
combinations in another code (and probably then have to change some of these tests...).
As for your comments:
k
andS
are regarded as 'soft' parameters so they don't cause an error if they are the wrong shape (I assume this is to allow flexibility e.g. inhelical
allows single or multiple spins) . Although this can lead to silently settingk
orS
to[]
if they are the wrong shape, this can happen easily if you get the S/k dimensions the wrong way round e.g. withswobj.genmagstr('mode', 'direct', 'S', ones(1, 3), 'k', ones(3, 1))
. Should we warn/error if this happens?
Yes!
random
mode actually readsk
even though it says it doesn't read anything in the docstring. It doesn't actually do anything with it, just sets it in the output struct. Is this intended? Should I update the docstring?
Yes! What this means is that it generates a random structure in the first unit cell and then it will apply the rotation frame with the default n
normal vector to this. Spin wave calculations will use the k
vector given - so the users should be aware of this. (Note also that the n
is also read in and used if k
is given - it basically behaves like helical
except that S
is randomly generated instead being specified).
direct
mode doesn't usen
even though it says it does in the docstring. Should I update this?
Yes, please!
- If
tile
mode is chosen and noS
is provided, it just sets the mode torandom
. Isn't this just the same as choosing random in the first place? We should either warn that this is happening or requireS
to be provided withtile
.
I think we should require that an S
be provided with tile
(replace line 308 with an error).
- I guess the
if ~cmplxS && ~strcmpi(param.mode,'fourier') && ~strcmpi(param.mode,'direct') && any(k(:))
line is converting the input spins into the Fourier components? ThecmplxS
check is a bit strange, is that implicitly checking whetherS
is already a Fourier component? But a user could just input a complexS
?
Yeah, it seems to be a way to implictly avoid using the n
vector since this is only used if the check passes (the n
vector is not otherwise used in helical
mode). It's not documented or used in any examples though, so I'm minded to introduce a check that helical
mode requires real S
(or a warning that a complex S
implies ignoring n
if n
is specified in helical
mode).
tile
mode sums over the third dimension ofS
(which is the multiple-k dimension), but without actually requiringk
as input, is this the behaviour we want? (seetest_tile_multik
)
I'm not sure... I think we keep the current test and behaviour but revisit it when we tackle multiple-k values (in the check of magstr
) and basically in addressing this user request issue
rotate
mode usesk
from existing magnetic structure, and silently ignores thek
input, is this desired?
I think that rotate
mode is meant to be used only after a magnetic structure has already been defined by another mode (certainly this is the case in all the tutorials it is used - 15, 21 (optmagsteep
automatically generates a random structure if nothing is defined) and 30.
So I think we should raise an error if no structure has been defined.
Changing the k
vector changes the magnetic structure drastically - a uniform rotation of the spin should mean that the spin wave dispersion is still the same (but the intensity at a given q-point might change). Changing k
would change the spin wave dispersion. I think that this is not the purpose of the rotate
mode (which is mostly used to make the magnetic structure figures look prettier by aligning the moments to an crystallographic axis or other such cosmetic changes). So, I think that if the use specifies a k
with the rotate
mode it should be an error (or at least a warning that the k
vector will be ignored).
extend
mode is undocumented and sets the mode totile
do we want to keep this or remove it?
As discussed I think this should be maintained for now with a deprecation warning on the use of extend
which is not used anywhere in the examples / tutorials. I think this was introduced later to be more inline with the syntax of other functions such as intmatrix
, but was never propagated. Since tile
is more often used I think we should deprecate extend
instead of tile
in this context.
- In
rotate
if the first spin is parallel ton
andphi=0
we getnRot=[0 0 0]
andS = NaN NaN NaN
. We should probably error in this case?
Yes, I think this should raise an error.
- If
nExt
is a scalar,nExt
is automatically determined fromk
. But what is the point in this? You still have to provide the correct number of spins so you could figure outnExt
yourself? See testtest_direct_multik_scalar_nExt
.
This is used to convert a structure from a rotating frame to a supercell and is used in tutorial 18 (there is a formatting error in this tutorial we should fix). So the idea is that you first create a structure with helical
or fourier
and do an incommensurate spin wave calculation then want to check if it is correct/equivalent by converting to a super cell with a scalar nExt
and doing a commensurate calculation. In some cases of complex structures, the incommensurate calculation might not be correct...
- In
rotate
mode, ifphi
is imaginary it appears to rotate first spin to[1 0 0]
(I don't really understand the code here though). This is undocumented. Should we document or remove this? Seetest_rotate_complex_phi
.
I don't understand this behaviour either... it seems to be an undocumented short hand to align the structure so that components the first spin perpendicular to n
is parallel to [1 0 0]
but it doesn't work if the first spin is parallel to n
.
I think this might just be a weird short hand which Sandor introduced for his own use which we can just remove (it's not documented anywhere or used in the code anywhere else...). So maybe we can just remove this code and raise an error if an imaginary / complex input is given for phi
or phid
- and see if any users complain ;)
So, for Now, if
You'd see that the intermediate spins are half of the main length rather than zero (they should in principle follow a sinusoidal dependence, Edit: I'm not sure if we should warn users about this or not... |
Thanks @mducle I think I get it... but it can lead to some unexpected (at least to me) results! So if I understand correctly, if |
@RichardWaiteSTFC I think that by definition, in a helical magnet the moments must lie on a plane. In SpinW, Maybe we should emit a warning if there is a component of Now, if what you really want with |
Good point - the structure I was talking about wasn't helical in the sense that it is normally understood to be rotating in a plane orthogonal to
Agreed changing the
I think a warning would be helpful, just to say the plane of the moments will be normal to the vector |
Really minor but would it be possible to clarify the docstring the say spinw/swfiles/@spinw/genmagstr.m Lines 139 to 142 in 8c2a818
|
The code coverage indicates this branch hasn;t been hit spinw/swfiles/@spinw/genmagstr.m Lines 329 to 332 in 8c2a818
But it looks like it is impossible to throw this error due to the size validation in the input to sw_readparam - perhaps it's worth deleting?
|
There seems to be validation around ensuring the supercell (if using) has to match the |
Should probably throw a warning if |
There seems to be a problem if you specify a complex
The call to
Note that the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job, I think it's probably worth adding a few things:
- A test with
epsilon
explicitly provided (see suggestion in attached comments) - A test with
norm=false
(i.e. taking the magnitude of the spin fromS
input) e.g.
testCase.swobj = spinw;
testCase.swobj.genlattice('lat_const', [3 8 8], 'angled', [90 90 90]);
testCase.swobj.addatom('r', [0 0 0],'S', 2, 'label', 'MNi2');
testCase.swobj.gencoupling('maxDistance', 7);
testCase.swobj.addmatrix('value', -eye(3), 'label', 'Ja');
testCase.swobj.addcoupling('mat', 'Ja', 'bond', 1);
testCase.swobj.genmagstr('mode', 'helical', 'S', [1; 0; 0], 'n', [0,1,0], 'k', [1/3 0 0], 'norm', false)
mgstr = testCase.swobj.magstr();
S = mgstr.S % [1,0,0]
testCase.swobj.genmagstr('mode', 'helical', 'S', [1; 0; 0], 'n', [0,1,0], 'k', [1/3 0 0], 'norm', true)
mgstr = testCase.swobj.magstr();
S = mgstr.S % [2,0,0]
- Add a warning (and test) for when
n
has a component parallel toS
in helical mode - A warning if
n
is complex (I don't think it's worth doing such a check for all other parameters - it's just this does cause a crash whenmagstr
is called)
- Specify n is converted to a unit vector in docstring - Remove unreachable n/k size error check
- Also move 'extend' -> 'tile' to the top so tile can be used in unused input checks - Also move valid mode check to in unused warning checks so an invalid mode isn't searched for in the struct
- Also move errors before warnings
5887b8c
to
e8afe01
Compare
Done in d8d54f3, have extended it to other parameters, probably overkill but wasn't too difficult to implement.
Done in ca2c7af, again probably overkill to check other parameters too but it seemed to not be much more effort...
Ah good spot I missed that! Done.
Oops, completely forgot about that parameter, done.
Done.
It errors rather than warning to avoid the crash, but also done. |
Inspecting varargin is more complex than initially thought, sometimes it can be a struct (e.g. when called from optmagk)
When called from places like optmagstr, varargin is actually a struct. Also, the struct contains many other additional parameters to do with fitting, so before calling genmagstr in optmagstr, warning('off','sw_readparam:UnreadInput') is called. This stops sw_readparam from issuing warnings. This also stops the `spinw:genmagstr:UnreadInput` warning from being triggered, which is why its name has been changed to UnreadInput, to avoid ugly unecessary warnings.
I didn't realise In addition to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks for taking on this tough one!
There's not so many lines of code in this one, but lots of branching which has made it a bit tricky. I've found a fairly big list of things while doing this that we might want to fix, document or make an issue for:
k
andS
are regarded as 'soft' parameters so they don't cause an error if they are the wrong shape (I assume this is to allow flexibility e.g. inhelical
allows single or multiple spins) . Although this can lead to silently settingk
orS
to[]
if they are the wrong shape, this can happen easily if you get the S/k dimensions the wrong way round e.g. withswobj.genmagstr('mode', 'direct', 'S', ones(1, 3), 'k', ones(3, 1))
. Should we warn/error if this happens?random
mode actually readsk
even though it says it doesn't read anything in the docstring. It doesn't actually do anything with it, just sets it in the output struct. Is this intended? Should I update the docstring?direct
mode doesn't usen
even though it says it does in the docstring. Should I update this?tile
mode is chosen and noS
is provided, it just sets the mode torandom
. Isn't this just the same as choosing random in the first place? We should either warn that this is happening or requireS
to be provided withtile
.if ~cmplxS && ~strcmpi(param.mode,'fourier') && ~strcmpi(param.mode,'direct') && any(k(:))
line is converting the input spins into the Fourier components? ThecmplxS
check is a bit strange, is that implicitly checking whetherS
is already a Fourier component? But a user could just input a complexS
?tile
mode sums over the third dimension ofS
(which is the multiple-k dimension), but without actually requiringk
as input, is this the behaviour we want? (seetest_tile_multik
)rotate
mode usesk
from existing magnetic structure, and silently ignores thek
input, is this desired?extend
mode is undocumented and sets the mode totile
do we want to keep this or remove it?rotate
if the first spin is parallel ton
andphi=0
we getnRot=[0 0 0]
andS = NaN NaN NaN
. We should probably error in this case?nExt
is a scalar,nExt
is automatically determined fromk
. But what is the point in this? You still have to provide the correct number of spins so you could figure outnExt
yourself? See testtest_direct_multik_scalar_nExt
.rotate
mode, ifphi
is imaginary it appears to rotate first spin to[1 0 0]
(I don't really understand the code here though). This is undocumented. Should we document or remove this? Seetest_rotate_complex_phi
.Probably a lot of this could be fixed by some better validation, which could be made easier if each mode was in its own function with its own validation and
genmagstr
was just wrapper, but that's probably for another time.