def test_symbolic_fourier_components(self): m = Sample() load_xsf(m, os.path.join(self._stdir,'crys.xsf')) rand_k = np.random.rand(3) rand_real_fc = np.random.rand(3).reshape((1,3))+0.j # make array complex mm = MM(1) mm.k=np.array(rand_k) mm.fc_set(rand_real_fc) m.mm = mm m.add_muon([0.1,0.1,0.1]) r = locfield(m, 's',[10,10,10],40)[0] if have_sympy: smm = SMM(1,"x,y,z") smm.k=np.array(rand_k) smm.set_symFC("[[x,y,z]]") smm.set_params(rand_real_fc[0].real.tolist()) m.mm = smm r2 = locfield(m, 's',[10,10,10],40)[0] self.assertAlmostEqual( r.D[0], r2.D[0], places=10, msg=None, delta=None) self.assertAlmostEqual( r.D[1], r2.D[1], places=10, msg=None, delta=None) self.assertAlmostEqual( r.D[2], r2.D[2], places=7, msg=None, delta=None)
def test_wrong_init(self): with self.assertRaises(TypeError): mm = MM(None) with self.assertRaises(ValueError): mm = MM('a') with self.assertRaises(ValueError): mm = MM(-1)
def test_compare_ass_and_rass(self): m = Sample() load_xsf(m, os.path.join(self._stdir, 'crys2.xsf')) mm = MM(9) mm.k = np.array(np.random.rand(3)) mm.fc_set( (np.random.rand(27) + 1.j * np.random.rand(27)).reshape(9, 3)) m.mm = mm m.add_muon(np.random.rand(3)) m.add_muon(np.random.rand(3)) r1 = locfield(m, 's', [10, 10, 10], 20) r2 = locfield(m, 'r', [10, 10, 10], 20, axis=[1, 1, 1], nangles=1) r1[0].ACont = 1.0 r2[0].ACont = 1.0 r1[1].ACont = 1.0 r2[1].ACont = 1.0 min_oom = min(self.oom(r1[0].T), self.oom(r2[0].T[0])) np.testing.assert_array_almost_equal(r1[0].T, r2[0].T[0], decimal=6 - min_oom) min_oom = min(self.oom(r1[1].T), self.oom(r2[1].T[0])) np.testing.assert_array_almost_equal(r1[1].T, r2[1].T[0], decimal=6 - min_oom)
def test_double_moment(self): m = Sample() load_xsf(m, os.path.join(self._stdir, 'crys.xsf')) mm = MM(1) mm.k = np.array([0., 0., 0.]) mm.fc_set(np.array([[0. + 0j, 0., 1. + 0.j]])) m.mm = mm m.add_muon([0.1, 0.1, 0.1]) r = locfield(m, 's', [1, 1, 1], 4)[0] m.mm.fc_set(np.array([[0. + 0j, 0. + 0.j, 2. + 0.j]])) r2 = locfield(m, 's', [1, 1, 1], 4)[0] # r should be: [0 tesla, 11.4226 milliteslas, 11.4226 milliteslas] # # (magnetic_constant/4pi)⋅((1/(1angstrom⋅sqrt(2.5^2+2.5^2+2.5^2)))^3)⋅(3⋅(1 bohr_magneton)⋅cos(atan(sqrt(2)))⋅([1,1,1]/sqrt(3))−1bohr_magneton⋅[1,0,0]) # # self.assertAlmostEqual(r.D[0], 0.5 * r2.D[0], places=10, msg=None, delta=None) self.assertAlmostEqual(r.D[1], 0.5 * r2.D[1], places=10, msg=None, delta=None) self.assertAlmostEqual(r.D[2], 0.5 * r2.D[2], places=7, msg=None, delta=None)
def test_compare_rass_and_incass(self): m = Sample() load_xsf(m, os.path.join(self._stdir,'crys.xsf')) mm = MM(1) # define three orthogonal vectors rp1 = np.random.rand(3) # used for k r2 = np.random.rand(3) rp2 = np.cross(rp1,r2) rp3 = np.cross(rp1,rp2) # normalize a and b vectors rp2 /= np.linalg.norm(rp2) rp3 /= np.linalg.norm(rp3) #chose a random value for stag moment stm = np.random.ranf()*10. rp2 *= stm rp3 *= stm mm.k=np.array(rp1) mm.fc_set((rp2+1.j*rp3).reshape(1,3)) m.mm = mm m.add_muon(np.random.rand(3)) m.add_muon(np.random.rand(3)) r1 = locfield(m, 's',[50,50,50],50) r2 = locfield(m, 'r',[50,50,50],50,nangles=1200,axis=rp1) r3 = locfield(m, 'i',[50,50,50],50,nangles=1200) r1[0].ACont = 1.0 r2[0].ACont = 1.0 r3[0].ACont = 1.0 r1[1].ACont = 1.0 r2[1].ACont = 1.0 r3[1].ACont = 1.0 min_oom = min(self.oom(r1[0].T), self.oom(r2[0].T[0])) np.testing.assert_array_almost_equal(r1[0].T,r2[0].T[0],decimal=7-min_oom) min_oom = min(self.oom(r1[1].T), self.oom(r2[1].T[0])) np.testing.assert_array_almost_equal(r1[1].T,r2[1].T[0],decimal=7-min_oom) r2_norms = np.apply_along_axis(np.linalg.norm, 1, r2[0].D) r3_norms = np.apply_along_axis(np.linalg.norm, 1, r3[0].D) min_oom=min(self.oom(np.max(r2_norms)), self.oom(np.max(r3_norms))) np.testing.assert_array_almost_equal(np.max(r2_norms),np.max(r3_norms),decimal=4-min_oom) min_oom=min(self.oom(np.min(r2_norms)), self.oom(np.min(r3_norms))) np.testing.assert_array_almost_equal(np.min(r2_norms),np.min(r3_norms),decimal=4-min_oom) r2_norms = np.apply_along_axis(np.linalg.norm, 1, r2[1].T) r3_norms = np.apply_along_axis(np.linalg.norm, 1, r3[1].T) min_oom=min(self.oom(np.max(r2_norms)), self.oom(np.max(r3_norms))) np.testing.assert_array_almost_equal(np.max(r2_norms),np.max(r2_norms),decimal=5-min_oom) min_oom=min(self.oom(np.min(r2_norms)), self.oom(np.min(r3_norms))) np.testing.assert_array_almost_equal(np.min(r3_norms),np.min(r3_norms),decimal=5-min_oom)
def test_one_dipole_outside(self): m = Sample() load_xsf(m, os.path.join(self._stdir, 'crys.xsf')) mm = MM(1) mm.k = np.array([0., 0., 0.]) mm.fc_set(np.array([[1. + 0j, 0. + 1.j, 0. + 1.j]])) m.mm = mm m.add_muon([0.5, 0.5, 0.5]) # the diagonal is 8.6603 r = locfield(m, 's', [1, 1, 1], 8.66 / 2.)[0] self.assertEqual(np.sum(np.abs(r.D)), 0.)
def test_one_dipole_outside(self): m = Sample() load_xsf(m, os.path.join(self._stdir,'crys.xsf')) mm = MM(1) mm.k=np.array([0.,0.,0.]) mm.fc_set(np.array([[1.+0j,0.+1.j,0.+1.j]])) m.mm = mm m.add_muon([0.5,0.5,0.5]) # the diagonal is 8.6603 r = locfield(m, 's',[1,1,1],8.66/2.)[0] self.assertEqual( np.sum(np.abs(r.D)), 0.)
def test_one_dipole_inside(self): m = Sample() load_xsf(m, os.path.join(self._stdir, 'crys.xsf')) mm = MM(1) mm.k = np.array([0., 0., 0.]) mm.fc_set(np.array([[1. + 0j, 0. + 0.j, 0. + 0.j]])) m.mm = mm m.add_muon([0.5, 0.5, 0.5]) r = locfield(m, 's', [1, 1, 1], 8.67 / 2.)[0] # BDip should be: [0 tesla, 11.4226 milliteslas, 11.4226 milliteslas] # # (magnetic_constant/4pi)⋅((1/(1angstrom⋅sqrt(2.5^2+2.5^2+2.5^2)))^3)⋅(3⋅(1 bohr_magneton)⋅cos(atan(sqrt(2)))⋅([1,1,1]/sqrt(3))−1bohr_magneton⋅[1,0,0]) # # BLor should be: [ 0.01138414 T, 0 , 0 ] # # 0.3333333333⋅magnetic_constant (1 bohr_magneton)/((4/3)pi(angstrom 8.67/2.)^3) # # BCont should be (Assuming ACont = 1 AA^-3 ) # # (2/3)⋅magnetic_constant (1 bohr_magneton)⋅(1angstrom^−3) = 7.769376 T # self.assertAlmostEqual(r.D[0], 0., places=7, msg=None, delta=None) self.assertAlmostEqual(r.D[1], r.D[2], places=10, msg=None, delta=None) self.assertAlmostEqual(r.D[1], 11.4226e-3, places=7, msg=None, delta=None) self.assertAlmostEqual(r.L[0], 0.01138414, places=7, msg=None, delta=None) self.assertAlmostEqual(r.L[1], 0.0, places=7, msg=None, delta=None) self.assertAlmostEqual(r.L[2], 0.0, places=7, msg=None, delta=None) r.ACont = 1. # Ang^-3 self.assertAlmostEqual(r.C[0], 7.769376, places=7, msg=None, delta=None) self.assertAlmostEqual(r.C[1], 0.0, places=7, msg=None, delta=None) self.assertAlmostEqual(r.C[2], 0.0, places=7, msg=None, delta=None)
def mago_add(sample, coordinates='b-c', fcs=None, kvalue=None): """ Adds a magnetic model (fourier components and K vector). The order is automatically selected if succesfully added. :param sample: A sample object. :param string coordinates: coordinates system and units of the Fourier components. Options are: 'b-c', 'b/a-l', 'b-l'. b-c : Fourier components in Bohr magnetons and Cartesian coordinates. b/a-l: Fourier components in Bohr magnetons/Angstrom and lattice coordinates. b-l : Fourier components in Bohr magnetons and in lattice coordinates. :param np.complex fcs: Fourier components in coordinate system (default: Bohr magnetoc/ Cartesian coordinates) :param np.ndarray kvalue: Propagation vector in r.l.u. :returns: True if successful, False otherwise. :rtype: bool """ nmm = MM(sample.cell.get_number_of_atoms(), sample.cell.get_cell()) ret = mago_set_k(sample, mm=nmm, kvalue=kvalue) if not ret: return False ret = mago_set_FC(sample, mm=nmm, inputConvention=coordinates, fcs=fcs) if not ret: return False sample.mm = nmm return True
def test_cubic_sym1(self): m = Sample() load_xsf(m, os.path.join(self._stdir,'crys.xsf')) mm = MM(1) mm.k=np.array([0.,0.,0.]) mm.fc_set(np.array([[1.+0j,0.+0.j,0.+0.j]])) m.mm = mm m.add_muon([0.5,0.5,0.5]) r = locfield(m, 's',[100,100,100],240)[0] # Bdip should be: [0 tesla, 11.4226 milliteslas, 11.4226 milliteslas] # # (magnetic_constant/4pi)⋅((1/(1angstrom⋅sqrt(2.5^2+2.5^2+2.5^2)))^3)⋅(3⋅(1 bohr_magneton)⋅cos(atan(sqrt(2)))⋅([1,1,1]/sqrt(3))−1bohr_magneton⋅[1,0,0]) # # self.assertAlmostEqual( r.D[0], r.D[1],places=10, msg=None, delta=None) self.assertAlmostEqual( r.D[0], r.D[2], places=10, msg=None, delta=None) self.assertAlmostEqual( r.D[0], 0., places=7, msg=None, delta=None)
def test_rotation(self): m = Sample() load_xsf(m, os.path.join(self._stdir,'crys3.xsf')) mm = MM(1) mm.k=np.array([0.,0.,0.]) mm.fc_set(np.array([[0.+0j,1.+0.j,0.+0.j]])) m.mm = mm m.add_muon([0.0,0.001,0.0]) r = locfield(m, 'r',[1,1,1],1.2,nnn=0,nangles=300,axis=[1,0,0])[0] # r for angle = 0 should be: [0 T, 1.8548 T, 0 T] # # (magnetic_constant/4pi)⋅((1/(1angstrom⋅sqrt(1^2)))^3)⋅(3⋅(1 bohr_magneton)⋅cos(0)⋅([0,1,0]/sqrt(1))−1bohr_magneton⋅[0,1,0]) # # # r for angle = 90 should be: [0 T, 0 T, −0.927401 T] # # (magnetic_constant/4pi)⋅((1/(1angstrom⋅sqrt(1^2)))^3)⋅(3⋅(1 bohr_magneton)⋅cos(pi/2)⋅([0,1,0]/sqrt(1))−1bohr_magneton⋅[0,0,1]) # # Opposite moments produce opposite fields. 150 is half of 300 np.testing.assert_array_almost_equal(r.D[0],-r.D[150],decimal=7) np.testing.assert_array_almost_equal(r.D[0],np.array([0., 1.8548018,0.]),decimal=7) np.testing.assert_array_almost_equal(r.D[75],np.array([0., 0,-0.9274009]),decimal=6) rnorms = np.apply_along_axis(np.linalg.norm,1,r.T-r.L) self.assertAlmostEqual( np.min(rnorms), 0.9274009 ,places=6, msg=None, delta=None) self.assertAlmostEqual( np.max(rnorms), 1.8548018 ,places=6, msg=None, delta=None) r = locfield(m, 'r',[5,1,1],1.5,nnn=0,nangles=300,axis=[1,0,0])[0] np.testing.assert_array_almost_equal(r.D[0],-r.D[150],decimal=7) np.testing.assert_array_almost_equal(r.D[0],np.array([0., 2.18268753,0.]),decimal=7) np.testing.assert_array_almost_equal(r.D[75],np.array([0., 0,-1.58317237]),decimal=6) rnorms = np.apply_along_axis(np.linalg.norm,1,r.T-r.L) self.assertAlmostEqual( np.min(rnorms), 1.58317237 ,places=6, msg=None, delta=None) self.assertAlmostEqual( np.max(rnorms), 2.18268753 ,places=6, msg=None, delta=None) # Now test incomm mm = MM(1) mm.k=np.array([0.,0.,0.]) mm.fc_set(np.array([[0.+0j,1.+0.j,0.+1.j]])) m.mm = mm i = locfield(m, 'i',[1,1,1],1.2,nnn=0,nangles=300)[0] inorms = np.apply_along_axis(np.linalg.norm,1,i.T-i.L) self.assertAlmostEqual( np.min(inorms), 0.9274009 ,places=6, msg=None, delta=None) self.assertAlmostEqual( np.max(inorms), 1.8548018 ,places=6, msg=None, delta=None) i = locfield(m, 'i',[5,1,1],1.5,nnn=0,nangles=300)[0] rnorms = np.apply_along_axis(np.linalg.norm,1,i.T-i.L) self.assertAlmostEqual( np.min(rnorms), 1.58317237 ,places=6, msg=None, delta=None) self.assertAlmostEqual( np.max(rnorms), 2.18268753 ,places=6, msg=None, delta=None)
def test_symbolic_fourier_components(self): m = Sample() load_xsf(m, os.path.join(self._stdir, 'crys.xsf')) rand_k = np.random.rand(3) rand_real_fc = np.random.rand(3).reshape( (1, 3)) + 0.j # make array complex mm = MM(1) mm.k = np.array(rand_k) mm.fc_set(rand_real_fc) m.mm = mm m.add_muon([0.1, 0.1, 0.1]) r = locfield(m, 's', [10, 10, 10], 40)[0] if have_sympy: smm = SMM(1, "x,y,z") smm.k = np.array(rand_k) smm.set_symFC("[[x,y,z]]") smm.set_params(rand_real_fc[0].real.tolist()) m.mm = smm r2 = locfield(m, 's', [10, 10, 10], 40)[0] self.assertAlmostEqual(r.D[0], r2.D[0], places=10, msg=None, delta=None) self.assertAlmostEqual(r.D[1], r2.D[1], places=10, msg=None, delta=None) self.assertAlmostEqual(r.D[2], r2.D[2], places=7, msg=None, delta=None)
def new_mm(self): """ Creates a new empty magnetic model (everything is set to zero) :returns: None :rtype: None """ self._check_lattice() self._magdefs.append(MM(self._cell.get_number_of_atoms(), self._cell.get_cell())) self._selected_mm = len(self._magdefs) - 1
def test_compare_ass_and_rass(self): m = Sample() load_xsf(m, os.path.join(self._stdir,'crys2.xsf')) mm = MM(9) mm.k=np.array(np.random.rand(3)) mm.fc_set((np.random.rand(27)+1.j*np.random.rand(27)).reshape(9,3)) m.mm = mm m.add_muon(np.random.rand(3)) m.add_muon(np.random.rand(3)) r1 = locfield(m, 's',[10,10,10],20) r2 = locfield(m, 'r',[10,10,10],20,axis=[1,1,1],nangles=1) r1[0].ACont = 1.0 r2[0].ACont = 1.0 r1[1].ACont = 1.0 r2[1].ACont = 1.0 min_oom = min(self.oom(r1[0].T), self.oom(r2[0].T[0])) np.testing.assert_array_almost_equal(r1[0].T,r2[0].T[0],decimal=6-min_oom) min_oom = min(self.oom(r1[1].T), self.oom(r2[1].T[0])) np.testing.assert_array_almost_equal(r1[1].T,r2[1].T[0],decimal=6-min_oom)
def test_mm_property(self): self._sample._reset(cell=True, magdefs=True, muon=True, sym=True) with self.assertRaises(MagDefError): self._sample.mm with self.assertRaises(CellError): self._sample.mm = MM(19) # randomly large number self._sample._reset(magdefs=True) self._set_a_cell() with self.assertRaises(TypeError): self._sample.mm = 1 self._sample._reset(magdefs=True, cell=True, muon=True, sym=True) self._sample.cell = Atoms(symbols=['C'], scaled_positions=[[0, 0, 0]], cell=[[3., 0, 0], [0, 3., 0], [0, 0, 3.]]) with self.assertRaises(MagDefError): self._sample.mm = MM(198) # randomly large number self._sample.mm = MM(1)
def test_one_dipole_inside(self): m = Sample() load_xsf(m, os.path.join(self._stdir,'crys.xsf')) mm = MM(1) mm.k=np.array([0.,0.,0.]) mm.fc_set(np.array([[1.+0j,0.+0.j,0.+0.j]])) m.mm = mm m.add_muon([0.5,0.5,0.5]) r = locfield(m,'s',[1,1,1],8.67/2.)[0] # BDip should be: [0 tesla, 11.4226 milliteslas, 11.4226 milliteslas] # # (magnetic_constant/4pi)⋅((1/(1angstrom⋅sqrt(2.5^2+2.5^2+2.5^2)))^3)⋅(3⋅(1 bohr_magneton)⋅cos(atan(sqrt(2)))⋅([1,1,1]/sqrt(3))−1bohr_magneton⋅[1,0,0]) # # BLor should be: [ 0.01138414 T, 0 , 0 ] # # 0.3333333333⋅magnetic_constant (1 bohr_magneton)/((4/3)pi(angstrom 8.67/2.)^3) # # BCont should be (Assuming ACont = 1 AA^-3 ) # # (2/3)⋅magnetic_constant (1 bohr_magneton)⋅(1angstrom^−3) = 7.769376 T # self.assertAlmostEqual( r.D[0], 0.,places=7, msg=None, delta=None) self.assertAlmostEqual( r.D[1], r.D[2], places=10, msg=None, delta=None) self.assertAlmostEqual( r.D[1], 11.4226e-3, places=7, msg=None, delta=None) self.assertAlmostEqual( r.L[0], 0.01138414 ,places=7, msg=None, delta=None) self.assertAlmostEqual( r.L[1], 0.0 ,places=7, msg=None, delta=None) self.assertAlmostEqual( r.L[2], 0.0 ,places=7, msg=None, delta=None) r.ACont = 1. # Ang^-3 self.assertAlmostEqual( r.C[0], 7.769376 ,places=7, msg=None, delta=None) self.assertAlmostEqual( r.C[1], 0.0 ,places=7, msg=None, delta=None) self.assertAlmostEqual( r.C[2], 0.0 ,places=7, msg=None, delta=None)
def test_magmodel_input(self): m = Sample() load_mcif(m, os.path.join(self._stdir, 'LiFeSO4F.mcif')) fcs_mcif = m.mm.fc #print(fcs_mcif) nmm = MM(m._cell.get_number_of_atoms(), m._cell.get_cell()) fcs = np.zeros([m.cell.get_number_of_atoms(), 3], dtype=np.complex) fcs[1:3] = np.array([[0.166987, -0.248559, 0.188134], [-0.166987, 0.248559, -0.188134]]) fcs[16:18] = np.array([[0.166987, -0.248559, 0.188134], [-0.166987, 0.248559, -0.188134]]) fcs[18:20] = -np.array([[0.166987, -0.248559, 0.188134], [0.166987, -0.248559, 0.188134]]) fcs[20:22] = np.array([[0.166987, -0.248559, 0.188134], [0.166987, -0.248559, 0.188134]]) np.testing.assert_array_almost_equal(m.mm.fcLattBMA, fcs, decimal=4) m.mm.fc_set(fcs, 1) np.testing.assert_array_almost_equal(m.mm.fc, fcs_mcif, decimal=4) fcs = np.zeros([m.cell.get_number_of_atoms(), 3], dtype=np.complex) fcs[1:3] = np.array([[1.73, -2.73, 1.36], [-1.73, 2.73, -1.36]]) fcs[16:18] = np.array([[1.73, -2.73, 1.36], [-1.73, 2.73, -1.36]]) fcs[18:20] = -np.array([[1.73, -2.73, 1.36], [1.73, -2.73, 1.36]]) fcs[20:22] = np.array([[1.73, -2.73, 1.36], [1.73, -2.73, 1.36]]) np.testing.assert_array_almost_equal(m.mm.fcLattBM, fcs, decimal=4) m.mm.fc_set(fcs, 2) np.testing.assert_array_almost_equal(m.mm.fc, fcs_mcif, decimal=4)
def test_rotation(self): m = Sample() load_xsf(m, os.path.join(self._stdir, 'crys3.xsf')) mm = MM(1) mm.k = np.array([0., 0., 0.]) mm.fc_set(np.array([[0. + 0j, 1. + 0.j, 0. + 0.j]])) m.mm = mm m.add_muon([0.0, 0.001, 0.0]) r = locfield(m, 'r', [1, 1, 1], 1.2, nnn=0, nangles=300, axis=[1, 0, 0])[0] # r for angle = 0 should be: [0 T, 1.8548 T, 0 T] # # (magnetic_constant/4pi)⋅((1/(1angstrom⋅sqrt(1^2)))^3)⋅(3⋅(1 bohr_magneton)⋅cos(0)⋅([0,1,0]/sqrt(1))−1bohr_magneton⋅[0,1,0]) # # # r for angle = 90 should be: [0 T, 0 T, −0.927401 T] # # (magnetic_constant/4pi)⋅((1/(1angstrom⋅sqrt(1^2)))^3)⋅(3⋅(1 bohr_magneton)⋅cos(pi/2)⋅([0,1,0]/sqrt(1))−1bohr_magneton⋅[0,0,1]) # # Opposite moments produce opposite fields. 150 is half of 300 np.testing.assert_array_almost_equal(r.D[0], -r.D[150], decimal=7) np.testing.assert_array_almost_equal(r.D[0], np.array([0., 1.8548018, 0.]), decimal=7) np.testing.assert_array_almost_equal(r.D[75], np.array([0., 0, -0.9274009]), decimal=6) rnorms = np.apply_along_axis(np.linalg.norm, 1, r.T - r.L) self.assertAlmostEqual(np.min(rnorms), 0.9274009, places=6, msg=None, delta=None) self.assertAlmostEqual(np.max(rnorms), 1.8548018, places=6, msg=None, delta=None) r = locfield(m, 'r', [5, 1, 1], 1.5, nnn=0, nangles=300, axis=[1, 0, 0])[0] np.testing.assert_array_almost_equal(r.D[0], -r.D[150], decimal=7) np.testing.assert_array_almost_equal(r.D[0], np.array([0., 2.18268753, 0.]), decimal=7) np.testing.assert_array_almost_equal(r.D[75], np.array([0., 0, -1.58317237]), decimal=6) rnorms = np.apply_along_axis(np.linalg.norm, 1, r.T - r.L) self.assertAlmostEqual(np.min(rnorms), 1.58317237, places=6, msg=None, delta=None) self.assertAlmostEqual(np.max(rnorms), 2.18268753, places=6, msg=None, delta=None) # Now test incomm mm = MM(1) mm.k = np.array([0., 0., 0.]) mm.fc_set(np.array([[0. + 0j, 1. + 0.j, 0. + 1.j]])) m.mm = mm i = locfield(m, 'i', [1, 1, 1], 1.2, nnn=0, nangles=300)[0] inorms = np.apply_along_axis(np.linalg.norm, 1, i.T - i.L) self.assertAlmostEqual(np.min(inorms), 0.9274009, places=6, msg=None, delta=None) self.assertAlmostEqual(np.max(inorms), 1.8548018, places=6, msg=None, delta=None) i = locfield(m, 'i', [5, 1, 1], 1.5, nnn=0, nangles=300)[0] rnorms = np.apply_along_axis(np.linalg.norm, 1, i.T - i.L) self.assertAlmostEqual(np.min(rnorms), 1.58317237, places=6, msg=None, delta=None) self.assertAlmostEqual(np.max(rnorms), 2.18268753, places=6, msg=None, delta=None)
def load_sample(filename="", fileobj=None): """ This function load a sample from a file in YAML format. :param str filename: the filename used to store data. :param file fileobj: an optional file object. If specified, this supersede the filename input. :return: a sample object :rtype: :py:class:`~Sample` object or None :raises: ValueError, FileNotFoundError, IsADirectoryError """ # fail if YAML is not available if not have_yaml: warnings.warn("Warning, YAML python package not present!") return sample = Sample() data = {} if fileobj is None: if filename == "": raise ValueError("Specify filename or File object") with open(filename, 'r') as f: data = load(f, Loader=Loader) else: data = load(fileobj, Loader=Loader) if not (type(data) is dict): raise ValueError('Invalid data file. (problems with YAML?)') if data is None: raise ValueError('Invalid/empty data file. (problems with YAML?)') if 'Name' in data.keys(): sample.name = str(data['Name']) if 'Lattice' in data.keys(): l = data['Lattice'] spos = None cpos = None if 'ScaledPositions' in l.keys(): spos = np.array(l['ScaledPositions']) elif 'CartesianPositions' in l.keys(): cpos = np.array(l['CartesianPositions']) cell = None if 'Cell' in l.keys(): cell = np.array(l['Cell']) symbols = None if 'Symbols' in l.keys(): symbols = l['Symbols'] if (cell is None) or (symbols is None): warnings.warn('Cell not loaded!', RuntimeWarning) else: if not spos is None: sample.cell = Atoms(symbols=symbols, scaled_positions=spos, cell=cell, pbc=True) elif not cpos is None: sample.cell = Atoms(symbols=symbols, positions=cpos, cell=cell, pbc=True) else: warnings.warn('Cell not loaded!', RuntimeWarning) else: warnings.warn('Cell not loaded!', RuntimeWarning) if 'Muon' in data.keys(): m = data['Muon'] if 'Positions' in m: for p in m['Positions']: sample.add_muon(p) else: warnings.warn('Muon positions not loaded!', RuntimeWarning) else: warnings.warn('Muon positions not loaded!', RuntimeWarning) if 'Symmetry' in data.keys(): s = data['Symmetry'] if ('Number' in s.keys()) and \ ('Symbol' in s.keys()) and \ ('Rotations' in s.keys()) and \ ('Translations' in s.keys()): sample.sym = spacegroup_from_data( s['Number'], s['Symbol'], rotations=np.array(s['Rotations']), translations=np.array(s['Translations'])) else: warnings.warn('Symmetry not loaded.', RuntimeWarning) else: warnings.warn('Symmetry not loaded!', RuntimeWarning) if 'MagneticOrders' in data.keys(): m = data['MagneticOrders'] if len(m) > 0: msize = int(m['Size']) for mo in m['Orders']: if 'lattice' in mo.keys(): n = MM(msize, \ np.array(mo['lattice'])) else: n = MM(msize) sample.mm = n sample.mm.k = np.array(mo['k']) sample.mm.phi = np.array(mo['phi']) if 'desc' in mo.keys(): sample.mm.desc = str(mo['desc']) rfcs, ifcs = np.hsplit(np.array(mo['fc']), 2) if mo['format'].lower() in ['bohr-cartesian', 'b-c']: sample.mm.fcCart = (rfcs + 1.j * ifcs) elif mo['format'].lower() in ['bohr/angstrom-lattic', 'b/a-l']: sample.mm.fcLattBMA = (rfcs + 1.j * ifcs) elif mo['format'].lower() in ['bohr-lattice', 'b-l']: sample.mm.fcLattBM = (rfcs + 1.j * ifcs) else: raise ValueError( 'Invalid Fourier Components format specifier in YAML file.' ) else: warnings.warn('Magnetic definitions not loaded!', RuntimeWarning) else: warnings.warn('Magnetic definitions not loaded!', RuntimeWarning) return sample
def test_compare_rass_and_incass(self): m = Sample() load_xsf(m, os.path.join(self._stdir, 'crys.xsf')) mm = MM(1) # define three orthogonal vectors rp1 = np.random.rand(3) # used for k r2 = np.random.rand(3) rp2 = np.cross(rp1, r2) rp3 = np.cross(rp1, rp2) # normalize a and b vectors rp2 /= np.linalg.norm(rp2) rp3 /= np.linalg.norm(rp3) #chose a random value for stag moment stm = np.random.ranf() * 10. rp2 *= stm rp3 *= stm mm.k = np.array(rp1) mm.fc_set((rp2 + 1.j * rp3).reshape(1, 3)) m.mm = mm m.add_muon(np.random.rand(3)) m.add_muon(np.random.rand(3)) r1 = locfield(m, 's', [50, 50, 50], 50) r2 = locfield(m, 'r', [50, 50, 50], 50, nangles=1200, axis=rp1) r3 = locfield(m, 'i', [50, 50, 50], 50, nangles=1200) r1[0].ACont = 1.0 r2[0].ACont = 1.0 r3[0].ACont = 1.0 r1[1].ACont = 1.0 r2[1].ACont = 1.0 r3[1].ACont = 1.0 min_oom = min(self.oom(r1[0].T), self.oom(r2[0].T[0])) np.testing.assert_array_almost_equal(r1[0].T, r2[0].T[0], decimal=7 - min_oom) min_oom = min(self.oom(r1[1].T), self.oom(r2[1].T[0])) np.testing.assert_array_almost_equal(r1[1].T, r2[1].T[0], decimal=7 - min_oom) r2_norms = np.apply_along_axis(np.linalg.norm, 1, r2[0].D) r3_norms = np.apply_along_axis(np.linalg.norm, 1, r3[0].D) min_oom = min(self.oom(np.max(r2_norms)), self.oom(np.max(r3_norms))) np.testing.assert_array_almost_equal(np.max(r2_norms), np.max(r3_norms), decimal=4 - min_oom) min_oom = min(self.oom(np.min(r2_norms)), self.oom(np.min(r3_norms))) np.testing.assert_array_almost_equal(np.min(r2_norms), np.min(r3_norms), decimal=4 - min_oom) r2_norms = np.apply_along_axis(np.linalg.norm, 1, r2[1].T) r3_norms = np.apply_along_axis(np.linalg.norm, 1, r3[1].T) min_oom = min(self.oom(np.max(r2_norms)), self.oom(np.max(r3_norms))) np.testing.assert_array_almost_equal(np.max(r2_norms), np.max(r2_norms), decimal=5 - min_oom) min_oom = min(self.oom(np.min(r2_norms)), self.oom(np.min(r3_norms))) np.testing.assert_array_almost_equal(np.min(r3_norms), np.min(r3_norms), decimal=5 - min_oom)
def setUp(self): self.NUMFCS = 2 self._latt = np.random.rand(3, 3) self._mm = MM(self.NUMFCS, self._latt) self._mmnolat = MM(self.NUMFCS)
class TestMM(unittest.TestCase): def setUp(self): self.NUMFCS = 2 self._latt = np.random.rand(3, 3) self._mm = MM(self.NUMFCS, self._latt) self._mmnolat = MM(self.NUMFCS) def test_wrong_init(self): with self.assertRaises(TypeError): mm = MM(None) with self.assertRaises(ValueError): mm = MM('a') with self.assertRaises(ValueError): mm = MM(-1) def test_cannot_set_anything(self): with self.assertRaises(TypeError): self._mm.ciao = 2 def test_size_property(self): self.assertEqual(self._mm.size, self.NUMFCS) def test_lattice_params_property(self): np.testing.assert_array_equal(self._mm.lattice_params, self._latt) def test_k_property(self): np.testing.assert_array_equal(self._mm.k, np.zeros(3)) self._mm.k = np.array([0.1, 0.2, 0.3]) np.testing.assert_array_equal(self._mm.k, np.array([0.1, 0.2, 0.3])) with self.assertRaises(TypeError): self._mm.k = 1 with self.assertRaises(ValueError): self._mm.k = np.zeros(4) with self.assertRaises(ValueError): self._mm.k = np.zeros([4, 4]) with self.assertRaises(ValueError): self._mm.k = np.array(['a', 'a', 'a']) def test_fc_property(self): np.testing.assert_array_equal(self._mm.fc, np.zeros([self.NUMFCS, 3])) np.testing.assert_array_equal(self._mm.fcCart, np.zeros([self.NUMFCS, 3])) np.testing.assert_array_equal(self._mm.fcLattBMA, np.zeros([self.NUMFCS, 3])) np.testing.assert_array_equal(self._mm.fcLattBM, np.zeros([self.NUMFCS, 3])) with self.assertRaises(ValueError): np.testing.assert_array_equal(self._mmnolat.fcLattBMA, np.zeros([self.NUMFCS, 3])) with self.assertRaises(ValueError): np.testing.assert_array_equal(self._mmnolat.fcLattBM, np.zeros([self.NUMFCS, 3])) # check for conversions between formats randomfcs = np.random.rand(self.NUMFCS, 3) + 1.j * np.random.rand(self.NUMFCS, 3) origfcs = np.copy(randomfcs) #simple way to generate lists of the form [1, 2, 0, 1] i.e. first element equal to last conv_list = np.mod(np.array([0, 1, 2, 0]) + np.random.randint(3), 3) # convert from format in conv_list[0] to format in conv_list[1] and so on for i in range(3): self._mm.fc_set(randomfcs, int(conv_list[i])) randomfcs = self._mm.fc_get(int(conv_list[i + 1])) np.testing.assert_array_almost_equal(origfcs, randomfcs) self._mm.fc = randomfcs np.testing.assert_array_almost_equal(randomfcs, self._mm.fc) np.testing.assert_array_almost_equal(randomfcs, self._mm.fcCart) self._mm.fcCart = randomfcs np.testing.assert_array_almost_equal(randomfcs, self._mm.fc) np.testing.assert_array_almost_equal(randomfcs, self._mm.fcCart) self._mm.fcLattBMA = randomfcs np.testing.assert_array_almost_equal(randomfcs, self._mm.fcLattBMA) self._mm.fcLattBM = randomfcs np.testing.assert_array_almost_equal(randomfcs, self._mm.fcLattBM) # test wrong type with self.assertRaises(ValueError): self._mm.fcLattBM = np.zeros(3) with self.assertRaises(ValueError): self._mm.fcLattBM = np.zeros(3, dtype=np.complex) with self.assertRaises(ValueError): self._mm.fcLattBM = np.zeros(3, dtype=np.complex) with self.assertRaises(TypeError): self._mm.fc_set(np.zeros([2, 3], dtype=np.complex), 'cart') #must be int with self.assertRaises(ValueError): self._mm.fc_set(np.zeros([2, 3], dtype=np.complex), 4) #must 0,1,2 with self.assertRaises(TypeError): self._mm.fc_set('a', 1) #must 0,1,2 def test_phi_property(self): np.testing.assert_array_equal(self._mm.phi, np.zeros(self.NUMFCS)) randomphis = np.random.random(self.NUMFCS) self._mm.phi = randomphis np.testing.assert_array_equal(self._mm.phi, randomphis) randomphis = np.random.random(self.NUMFCS).tolist() self._mm.phi = randomphis np.testing.assert_array_equal(self._mm.phi, randomphis) with self.assertRaises(TypeError): self._mm.phi = 1 with self.assertRaises(ValueError): self._mm.phi = np.zeros([2, 3]) with self.assertRaises(ValueError): self._mm.phi = ['a'] with self.assertRaises(ValueError): self._mm.phi = np.array(['a', 'a']) def test_desc_property(self): self._mm.desc = "ciao" #test unicode self._mm.desc = u"ciao" self.assertEqual(self._mm.desc, "ciao") with self.assertRaises(TypeError): self._mm.desc = 1 def test_isSymbolic(self): self.assertEqual(self._mm.isSymbolic, False)
def load_mcif(sample, filename, reset_muon=True, reset_sym=True): """ Loads both the crystalline structure and the magnetic order from a mcif file. N.B.: This function is EXPERIMENTAL. .. note:: Only the first lattice and magnetic structure is loaded. mCif files hosting multiple structures are not supported. :param muesr.core.sample.Sample sample: the sample object. :param str filename: the mcif file path (path + filename). :param bool reset_muon: if true the muon positions is reinitialized. :param bool reset_sym: if true the symmetry is reinitialized. :returns: True if succesfull, false otherwise :rtype: bool """ # DEFINITION OF UNITS AND SETTINGS: http://cmswiki.byu.edu/wiki/Magnetic_Coordinates # new link http://magcryst.org/resources/magnetic-coordinates/ f = open(os.path.expanduser(filename),'r') data = parse_cif(f) f.close() #print('Parsing data from: ' + data[0][0]) tags = data[0][1] # Load symmetry #sym = tags2spacegroup(tags) # load cell info a = tags['_cell_length_a'] b = tags['_cell_length_b'] c = tags['_cell_length_c'] alpha = tags['_cell_angle_alpha'] beta = tags['_cell_angle_beta'] gamma = tags['_cell_angle_gamma'] # Find magnetic atoms mag_atoms_labels = tags['_atom_site_moment_label'] # load mag moments mag_atoms_moments = np.zeros([len(mag_atoms_labels),3],dtype=np.complex) scaled_positions = np.array([tags['_atom_site_fract_x'], tags['_atom_site_fract_y'], tags['_atom_site_fract_z']]).T scaled_positions = np.mod(scaled_positions, 1.) all_scaled_pos = np.copy(scaled_positions) symbols = [] if '_atom_site_type_symbol' in tags: labels = tags['_atom_site_type_symbol'] else: labels = tags['_atom_site_label'] for s in labels: # Strip off additional labeling on chemical symbols m = re.search(r'([A-Z][a-z]?)', s) symbol = m.group(0) symbols.append(symbol) fcs = np.zeros_like(all_scaled_pos,dtype=np.complex) for i, al in enumerate(tags['_atom_site_label']): if al in tags['_atom_site_moment_label']: mi = tags['_atom_site_moment_label'].index(al) fcs[i] = [complex(tags['_atom_site_moment_crystalaxis_x'][mi]), complex(tags['_atom_site_moment_crystalaxis_y'][mi]), complex(tags['_atom_site_moment_crystalaxis_z'][mi]) ] # THESE ARE IN CRYSTAL AXIS COORDINATE SYSTEM!!! # bohr magneton units are used # the magnetic metric tensor is M = L.G.L^(-1), which is unitless. # NOW GO TO REDUCED LATTICE COORDINATE SYSTEM TO DO THE SYMMETRY L = np.diag([1./a,1./b,1./c]) fcs = np.dot(fcs,L) # we copy the fourier components that were present in the mcif. # the others will be obtained from symmetry operations all_fcs = np.copy(fcs) for j, m_a_p in enumerate(scaled_positions): for cent in tags['_space_group_symop.magn_centering_xyz']: # magn_centering_xyz rc,tc,trc = parse_magn_operation_xyz_string(cent) # apply centering and go back to the unit cell cm_a_p = (np.dot(rc,m_a_p)+tc)%1. #print ('cmap is :' + str(cm_a_p)) for s in tags['_space_group_symop.magn_operation_xyz']: # magn_operation_xyz r,t,tr = parse_magn_operation_xyz_string(s) symp = (np.dot(r,cm_a_p)+t)%1. #print('Symp is: '+ str(symp)) # check if this position was already present for l, pp in enumerate(all_scaled_pos): if np.allclose(symp,pp,rtol=1e-3): break else: # Append position just found with symmetry symbols.append(symbols[j]) all_scaled_pos = np.append(all_scaled_pos,[symp],axis=0) # go to crystal units crysfc = trc*np.linalg.det(rc)*tr*np.linalg.det(r)*np.dot(r, np.dot(rc,fcs[j])) all_fcs = np.append(all_fcs ,[crysfc],axis=0) # mag_crys2car = cellpar_to_cell([a, b, c, alpha, beta, gamma], (0,0,1), None) # go to cartesian coordinates cartfc = np.dot(all_fcs,mag_crys2car) sample._reset(muon=reset_muon,sym=reset_sym) # symmetry is already introduced when parsing magnetism sample.cell, _ = crystal(symbols=symbols, basis=all_scaled_pos, cellpar=[a, b, c, alpha, beta, gamma]) # initialization needs the number of atoms in the unit cell nmm=MM(len(all_scaled_pos),sample._cell.get_cell()) # magnetic moments are specified in cartesian coordinates. # position in crystal coordinates...not nice but simple! nmm.fc_set(cartfc) # propagation vector is 0 since the cell "contains" the magnetic # structure, no incommensurate structures, sorry! nmm.k=np.array([0.,0.,0.]) sample.mm=nmm return True