SpinW / spinw

SpinW Matlab library for spin wave calculation
http://www.spinw.org
GNU General Public License v3.0
35 stars 15 forks source link

Fractional occupancy #201

Open SrimalR opened 1 month ago

SrimalR commented 1 month ago

Hi,

I am trying to calculate spin waves for a system with fractional occupancy using this code,

cnto = spinw;

cnto.genlattice('lat_const', [5.13860 5.13860 14.28570], 'angled', [90 90 120], 'sym', 'R -3');

cnto.addatom('r',[0 0 0.35200],'label','Co','occ',0.5,'formfact','MCo+2','S',1/2,'color','blue') cnto.addatom('r',[0 0 0.35200],'label','Ni','occ',0.5,'formfact','MNi+2','S',1,'color','blue')

cnto.gencoupling('maxDistance', 8, 'forceNoSym',true); plot(cnto, 'range',[1 1 1])..........

But I got this error,

Error using spinw/gencoupling Some atoms are too close (Dmin=0<0.5), check your crystal structure!

Error in CNTO (line 10) cnto.gencoupling('maxDistance', 8, 'forceNoSym',true);

Is it possible in spinW to handle fractional occupancies with different spins?

mducle commented 4 weeks ago

Hi @SrimalR - the occ option is basically there to handle loading CIF files and only affects the calculation of the diffraction structure factor using the structfact method (by scaling the calculated structure factor by the occupation so the diffraction peaks will be lower than if the site was fully occupied). It doesn't actually allow you to specify a site which is occupied by multiple magnetic atoms.

To handle a situation like you have - where Co and Ni are randomly distributed on the same site - you have to generate a large supercell and put specific Co or Ni ions in each, and then run the calculation for several different configurations and then average the result. This is the "supercell" approach, but will require relatively long calculation times.

The faster alternative is to create a single "virtual" atom which has say spin 0.75 which embodies a mix of Co and Ni. This would correspond to the "virtual crystal approximation" but has well known drawbacks which you can look up...

Unfortunately SpinW does not support calculations using the "coherent potential approximation" which is usually the best compromise between the supercell and VCA approaches.


An possible setup for your system is:

cnto = spinw;
cnto.genlattice('lat_const', [5.13860 5.13860 14.28570], 'angled', [90 90 120], 'sym', 'R -3');
cnto.addatom('r', [0 0 0.35200], 'label', 'Co', 'formfact', 'MCo+2', 'S', 1/2, 'color', 'blue');

% Generate a 2x2x2 supercell and switch half of the Co atoms to Ni.
cnto.newcell('bvect', diag([2 2 2]), 'keepq', true);
n_at = size(cnto.unit_cell.r, 2);
[~, ff_ni] = sw_mff('MNi2')
for ii = 1:n_at
    if rand > 0.5  % switch half of atoms to Ni
        cnto.unit_cell.S(ii) = 1;
        cnto.unit_cell.label{ii} = 'Ni';
        cnto.unit_cell.ff(1,[1:8 11],ii) = ff_ni;
        cnto.unit_cell.color(:,ii) = [255 0 0];
    end
end

cnto.gencoupling('maxDistance', 8);
% Set up nearest neighbour bonds
cnto.addmatrix('label', 'JNN', 'value', 1); % Ni-Ni coupling
cnto.addmatrix('label', 'JNC', 'value', 2); % Ni-Co coupling
cnto.addmatrix('label', 'JCC', 'value', 3); % Co-Co coupling
cnto.addcoupling('mat', 'JNN', 'bond', 1, 'atom', {'Ni', 'Ni'});
cnto.addcoupling('mat', 'JNC', 'bond', 1, 'atom', {'Ni', 'Co'});
cnto.addcoupling('mat', 'JNC', 'bond', 1, 'atom', {'Co', 'Ni'});
cnto.addcoupling('mat', 'JCC', 'bond', 1, 'atom', {'Co', 'Co'});

plot(cnto)
cnto.table('bond', 1)

You should then add code to calculate the spin waves - not forgetting to perform the configurational averaging!

SrimalR commented 4 weeks ago

Hi @mducle. Thank you for the response. This is an interesting way to do this. I will try this.

SrimalR commented 3 weeks ago

Hi @mducle . Is there a way to assign spins to this supercell type system. Do I need to do it manually one by one? My system has in plane spin orientation with in plane FM interaction and out of plane AFM interactions.

mducle commented 3 weeks ago

@SrimalR

For the spin orientations - it depends on whether the Ni spins are oriented differently from the Co spins. If you just have an averaged AFM structure (for example) then you can just input it before the section where the super cell is created and the "newcell" command will copy it onto the supercell. If the spin orientations of the Ni and Co are different then you'll have to assign it one by one in the loop.

For the interactions, you can check the bond table (produced by the last line in the code above) to see which one is in-plane and which is out-of-plane and adjust the values appropriately. (Positive numbers in the "addmatrix" command indicate antiferromagnetic interactions, negative are ferromagnetic).