public release 2.2.0 - see README.md and CHANGES.md for details

This commit is contained in:
2020-09-04 16:22:42 +02:00
parent fbd2d4fa8c
commit 7c61eb1b41
67 changed files with 2934 additions and 682 deletions

View File

@ -175,6 +175,22 @@ class TestClusterFunctions(unittest.TestCase):
np.testing.assert_allclose(layers, np.asarray([-0.3, -0.2, -0.1, 0.0, +0.1]), atol=0.001)
def test_get_center(self):
clu = mc.Cluster()
clu.add_atom(1, np.asarray([1, 0, 0]), 0)
clu.add_atom(2, np.asarray([0, 0, 1]), 0)
clu.add_atom(1, np.asarray([0, 1, 0]), 0)
clu.add_atom(2, np.asarray([-1, -1, -1]), 0)
v0 = np.asarray([0, 0, 0])
v1 = np.asarray([1/2, 1/2, 0])
v2 = np.asarray([-1/2, -1/2, 0])
v = clu.get_center()
np.testing.assert_allclose(v, v0, atol=0.001)
v = clu.get_center(element=1)
np.testing.assert_allclose(v, v1, atol=0.001)
v = clu.get_center(element="He")
np.testing.assert_allclose(v, v2, atol=0.001)
def test_relax(self):
clu = mc.Cluster()
clu.add_atom(1, np.asarray([1, 0, 1]), 0)
@ -184,7 +200,7 @@ class TestClusterFunctions(unittest.TestCase):
clu.add_atom(2, np.asarray([0, 1, -3]), 0)
idx = clu.relax(-0.3, -0.1, 2)
np.testing.assert_almost_equal(idx, np.asarray([[2, 4]]))
np.testing.assert_almost_equal(idx, np.asarray([2, 4]))
np.testing.assert_allclose(clu.get_position(0), np.asarray([1, 0, 1]), atol=1e-6)
np.testing.assert_allclose(clu.get_position(1), np.asarray([1, 0, 0]), atol=1e-6)
np.testing.assert_allclose(clu.get_position(2), np.asarray([0, 1, -1.1]), atol=1e-6)
@ -224,18 +240,81 @@ class TestClusterFunctions(unittest.TestCase):
np.testing.assert_allclose(clu.get_position(1), np.asarray([-1, 0, 0]), atol=1e-6)
np.testing.assert_allclose(clu.get_position(2), np.asarray([0, 0, 1]), atol=1e-6)
def test_translate(self):
clu = mc.Cluster()
clu.add_atom(1, np.asarray([1, 0, 0]), 0)
clu.add_atom(2, np.asarray([0, 1, 0]), 0)
clu.add_atom(3, np.asarray([0, 0, 1]), 0)
v = np.array((0.1, 0.2, 0.3))
shift = clu.translate(v)
np.testing.assert_allclose(clu.get_position(0), np.asarray([1.1, 0.2, 0.3]), atol=1e-6)
np.testing.assert_allclose(clu.get_position(1), np.asarray([0.1, 1.2, 0.3]), atol=1e-6)
np.testing.assert_allclose(clu.get_position(2), np.asarray([0.1, 0.2, 1.3]), atol=1e-6)
np.testing.assert_allclose(shift, np.asarray([0, 1, 2]))
shift = clu.translate(v, element=3)
np.testing.assert_allclose(clu.get_position(0), np.asarray([1.1, 0.2, 0.3]), atol=1e-6)
np.testing.assert_allclose(clu.get_position(1), np.asarray([0.1, 1.2, 0.3]), atol=1e-6)
np.testing.assert_allclose(clu.get_position(2), np.asarray([0.2, 0.4, 1.6]), atol=1e-6)
np.testing.assert_allclose(shift, np.asarray([2]))
def test_add_layer(self):
clu = mc.Cluster()
# from hbncu project
b_surf = 2.50
clu.set_rmax(4.0)
b1 = np.array((b_surf, 0.0, 0.0))
b2 = np.array((b_surf / 2.0, b_surf * math.sqrt(3.0) / 2.0, 0.0))
a1 = -10.0 * b1 - 10.0 * b2
emitter = np.array((0.0, 0.0, 0.0))
clu.set_rmax(2.0)
b1 = np.array((1.0, 0.0, 0.0))
b2 = np.array((0.0, 1.0, 0.0))
a1 = np.array((0.1, 0.0, -0.1))
clu.add_layer(7, a1, b1, b2)
pos = clu.find_positions(pos=emitter)
self.assertEqual(1, len(pos))
exp_pos = [[-0.9, -1.0, -0.1], [0.1, -1.0, -0.1], [1.1, -1.0, -0.1],
[-1.9, 0.0, -0.1], [-0.9, 0.0, -0.1], [0.1, 0.0, -0.1], [1.1, 0.0, -0.1],
[-0.9, 1.0, -0.1], [0.1, 1.0, -0.1], [1.1, 1.0, -0.1]]
nn = len(exp_pos)
self.assertEqual(nn, clu.data.shape[0])
self.assertEqual(nn, clu.get_atom_count())
act_pos = np.sort(clu.get_positions(), axis=0)
exp_pos = np.sort(np.array(exp_pos), axis=0)
np.testing.assert_allclose(act_pos, exp_pos)
act_idx = np.unique(clu.data['i'])
self.assertEqual(nn, act_idx.shape[0])
act_typ = (clu.data['t'] == 7).nonzero()[0]
self.assertEqual(nn, act_typ.shape[0])
def test_add_bulk(self):
clu = mc.Cluster()
clu.set_rmax(2.0)
b1 = np.array((1.0, 0.0, 0.0))
b2 = np.array((0.0, 1.0, 0.0))
b3 = np.array((0.0, 0.0, 1.0))
a1 = np.array((0.1, 0.0, -0.1))
z_surf = 0.8
clu.add_bulk(7, a1, b1, b2, b3, z_surf=z_surf)
r_great = max(clu.rmax, np.linalg.norm(a1))
n1 = max(int(r_great / np.linalg.norm(b1)) + 1, 4) * 3
n2 = max(int(r_great / np.linalg.norm(b2)) + 1, 4) * 3
n3 = max(int(r_great / np.linalg.norm(b3)) + 1, 4) * 3
exp_pos = []
nn = 0
for i1 in range(-n1, n1 + 1):
for i2 in range(-n2, n2 + 1):
for i3 in range(-n3, n3 + 1):
v = a1 + b1 * i1 + b2 * i2 + b3 * i3
if np.linalg.norm(v) <= clu.rmax and v[2] <= z_surf:
exp_pos.append(v)
nn += 1
self.assertEqual(nn, clu.data.shape[0])
self.assertEqual(nn, clu.get_atom_count())
act_pos = np.sort(clu.get_positions(), axis=0)
exp_pos = np.sort(np.array(exp_pos), axis=0)
np.testing.assert_allclose(act_pos, exp_pos)
act_idx = np.unique(clu.data['i'])
self.assertEqual(nn, act_idx.shape[0])
act_typ = (clu.data['t'] == 7).nonzero()[0]
self.assertEqual(nn, act_typ.shape[0])
def test_add_cluster(self):
clu1 = mc.Cluster()
@ -375,6 +454,18 @@ class TestClusterFunctions(unittest.TestCase):
f = BytesIO()
pos = np.asarray((-1, -1, 0))
clu.set_emitter(pos=pos)
clu.save_to_file(f, mc.FMT_PMSCO, "qwerty", emitters_only=True)
f.seek(0)
line = f.readline()
self.assertEqual(line, b"# index element symbol class x y z emitter charge\n", b"line 1: " + line)
line = f.readline()
self.assertRegexpMatches(line, b"[0-9]+ +1 +H +[0-9]+ +[0.]+ +[0.]+ +[0.]+ +1 +[0.]", b"line 3: " + line)
line = f.readline()
self.assertRegexpMatches(line, b"[0-9]+ +14 +Si +[0-9]+ +[01.-]+ +[01.-]+ +[0.]+ +1 +[0.]", b"line 4: " + line)
line = f.readline()
self.assertEqual(b"", line, b"end of file")
f = BytesIO()
clu.save_to_file(f, mc.FMT_XYZ, "qwerty", emitters_only=True)
f.seek(0)
line = f.readline()
@ -388,6 +479,37 @@ class TestClusterFunctions(unittest.TestCase):
line = f.readline()
self.assertEqual(b"", line, b"end of file")
def test_load_from_file(self):
f = BytesIO()
f.write(b"2\n")
f.write(b"qwerty\n")
f.write(b"H 0.5 0.6 0.7\n")
f.write(b"Si -1.5 -1.6 -1.7\n")
f.seek(0)
clu = mc.Cluster()
clu.load_from_file(f, fmt=mc.FMT_XYZ)
np.testing.assert_allclose(clu.data['t'], np.array([1, 14]))
np.testing.assert_allclose(clu.data['x'], np.array([0.5, -1.5]))
np.testing.assert_allclose(clu.data['y'], np.array([0.6, -1.6]))
np.testing.assert_allclose(clu.data['z'], np.array([0.7, -1.7]))
np.testing.assert_allclose(clu.data['e'], np.array([0, 0]))
np.testing.assert_allclose(clu.data['q'], np.array([0, 0]))
f = BytesIO()
f.write(b"# index element symbol class x y z emitter charge\n")
# ['i', 't', 's', 'c', 'x', 'y', 'z', 'e', 'q']
f.write(b"1 6 C 1 0.5 0.6 0.7 0 -0.5\n")
f.write(b"2 14 Si 2 -1.5 -1.6 -1.7 1 0.5\n")
f.seek(0)
clu = mc.Cluster()
clu.load_from_file(f, fmt=mc.FMT_PMSCO)
np.testing.assert_allclose(clu.data['t'], np.array([6, 14]))
np.testing.assert_allclose(clu.data['x'], np.array([0.5, -1.5]))
np.testing.assert_allclose(clu.data['y'], np.array([0.6, -1.6]))
np.testing.assert_allclose(clu.data['z'], np.array([0.7, -1.7]))
np.testing.assert_allclose(clu.data['e'], np.array([0, 1]))
np.testing.assert_allclose(clu.data['q'], np.array([-0.5, 0.5]))
def test_update_atoms(self):
clu = mc.Cluster()
clu.add_atom(1, np.asarray([0, 0, 0]), 1)
@ -409,3 +531,29 @@ class TestClusterFunctions(unittest.TestCase):
clu.update_atoms(other, {'c'})
expected = np.asarray((1, 3, 2, 3, 2, 4))
np.testing.assert_array_equal(expected, clu.data['c'])
def test_calc_scattering_angles(self):
clu = mc.Cluster()
ref_em = np.asarray([0.1, -0.1, 0.5])
ref_th = np.asarray([0., 15., 90., 100., 120.])
ref_ph = np.asarray([0., 90., 180., 270., 360.])
ref_di = np.asarray([0.5, 1.0, 1.5, 2.0, 2.5])
exp_th = ref_th[0:4]
exp_ph = ref_ph[0:4]
exp_di = ref_di[0:4]
sel_ph = exp_ph > 180.
exp_ph[sel_ph] = exp_ph[sel_ph] - 360.
idx_em = clu.add_atom(1, ref_em, 1)
for i, r in enumerate(ref_di):
v = np.asarray([
r * math.cos(math.radians(ref_ph[i])) * math.sin(math.radians(ref_th[i])) + ref_em[0],
r * math.sin(math.radians(ref_ph[i])) * math.sin(math.radians(ref_th[i])) + ref_em[1],
r * math.cos(math.radians(ref_th[i])) + ref_em[2]])
clu.add_atom(i, v, 0)
result = clu.calc_scattering_angles(idx_em, 2.2)
np.testing.assert_allclose(result['index'], np.arange(1, exp_di.shape[0] + 1))
np.testing.assert_allclose(result['polar'], exp_th, atol=1e-3)
np.testing.assert_allclose(result['azimuth'], exp_ph, atol=1e-3)
np.testing.assert_allclose(result['dist'], exp_di, rtol=1e-5)