mdkits 0.1.4__py3-none-any.whl → 0.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mdkits might be problematic. Click here for more details.

mdkits/cli/adsorbate.py CHANGED
@@ -34,6 +34,10 @@ def parse_argument():
34
34
 
35
35
  return parser.parse_args()
36
36
 
37
+ @click.option('--adsorbate', type=arg_type.Molecule, help='add adsorbate on surface')
38
+ @click.option('--site', type=click.Choice(['ontop', 'hollow','fcc', 'hcp', 'bridge', 'shortbridge', 'longbridge']))
39
+ @click.option('--height', type=float, help='height above the surface')
40
+ @click.option('--rotate', type=click.Tuple([float, float, float]), help='rotate adsorbate molcule around x, y, z axis', default=(0, 0, 0))
37
41
  def main():
38
42
  args = parse_argument()
39
43
  atoms = encapsulated_ase.atoms_read_with_cell(args.filename, cell=args.cell, coord_mode=args.coord)
@@ -47,6 +51,11 @@ def main():
47
51
  if atom.index in args.index:
48
52
  position_list.append(np.copy(atom.position[0:2])+offset)
49
53
 
54
+ molecule = build.molecule(adsorbate)
55
+ molecule.rotate(rotate[0], 'x')
56
+ molecule.rotate(rotate[1], 'y')
57
+ molecule.rotate(rotate[2], 'z')
58
+ build.add_adsorbate(atoms, molecule, position=site, height=height)
50
59
  if args.m in g2.names:
51
60
  molecule = build.molecule(args.m)
52
61
  if args.x:
mdkits/cli/build_bulk.py CHANGED
@@ -5,7 +5,7 @@ from ase.build import bulk
5
5
  import numpy as np
6
6
 
7
7
 
8
- @click.command(name='build_bulk')
8
+ @click.command(name='bulk')
9
9
  @click.argument('symbol', type=str)
10
10
  @click.argument('cs', type=click.Choice(['sc', 'fcc', 'bcc', 'tetragonal', 'bct', 'hcp', 'rhombohedral', 'orthorhombic', 'mcl', 'diamond', 'zincblende', 'rocksalt', 'cesiumchloride', 'fluorite', 'wurtzite']))
11
11
  @click.option('-a', type=float, help='designate lattice constant a')
@@ -0,0 +1,19 @@
1
+ import click
2
+ from mdkits.cli import (
3
+ build_bulk,
4
+ build_surface,
5
+ )
6
+
7
+
8
+ @click.group(name='build')
9
+ @click.pass_context
10
+ def cli_build(ctx):
11
+ """kits for building"""
12
+ pass
13
+
14
+
15
+ cli_build.add_command(build_bulk.main)
16
+ cli_build.add_command(build_surface.main)
17
+
18
+ if __name__ == '__main__':
19
+ cli_build()
@@ -1,132 +1,54 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
- import argparse, sys
3
+ import click
4
4
  from ase import build
5
- from ase.geometry import cell_to_cellpar
6
- from ase.io import write
7
5
  import numpy as np
8
6
 
9
7
 
10
-
11
- def parse_size(s):
12
- if s == None:
13
- return None
14
- return [int(x) for x in s.replace(',', ' ').split()]
15
-
16
-
17
8
  def surface_check(obj, surface_type):
18
9
  if hasattr(obj, surface_type):
19
10
  return getattr(obj, surface_type)
20
- else:
21
- print(f'dont have face named {surface_type}')
22
- exit()
23
11
 
24
12
 
25
- def parse_argument():
26
- parser = argparse.ArgumentParser(description='build a surface structure of matel')
27
- parser.add_argument('symbol', type=str, help='designate the symbol of matel')
28
- parser.add_argument('--face', type=str, help='designate the face of surface')
29
- parser.add_argument('-a', type=float, help='designate a lattice constant', default=None)
30
- parser.add_argument('--primitive', help='designate a lattice constant of real', action='store_true')
31
- parser.add_argument('--size', type=parse_size, help='designate surface size(a,b,c)')
32
- parser.add_argument('--vacuum', type=float, help='designate vacuum of surface, default is None', default=0.0)
33
- parser.add_argument('--adsorbate', type=str, help='add adsorbate on surface', default=None)
34
- parser.add_argument('--position', type=str, help='position of adsorbate', default='ontop')
35
- parser.add_argument('--offset', type=str, help='offset')
36
- parser.add_argument('--height', type=float, help='position of adsorbate', default=1)
37
- parser.add_argument('-o', type=str, help='output structure name', default='surface.xyz')
38
- parser.add_argument('-c', help='output coord.xyz and cell.inc', action='store_true')
39
- parser.add_argument('-k', type=parse_size, help='output kpoint.inc(a,b,c)', default=None)
40
- parser.add_argument('--autok', help='output kpoint.inc', action='store_true')
41
- parser.add_argument('--orth', help='orth cell', action='store_true')
42
- parser.add_argument('--coverh', type=int, help='cover H atom', default=0)
43
-
44
- return parser.parse_args()
45
-
46
-
47
- def main():
48
- args = parse_argument()
49
- if args.primitive:
50
- a = args.a * 0.7071 * 2
51
- else:
52
- a = args.a
53
-
54
- vacuum = args.vacuum / 2
55
-
56
- build_surface = surface_check(build, args.face)
57
-
58
- if args.orth:
59
- atoms = build_surface(args.symbol, args.size, a=a, vacuum=vacuum, orthogonal=args.orth)
60
- else:
61
- atoms = build_surface(args.symbol, args.size, a=a, vacuum=vacuum)
62
-
63
- # add adsorbate
64
- if args.adsorbate != None:
65
- ## add H2Oa and OH
66
- if args.adsorbate in ['H2Oa', 'OH']:
67
- if args.adsorbate in ['OH']:
68
- h2o = build.molecule(args.adsorbate)
69
- h2o.rotate(90, 'y')
70
- build.add_adsorbate(atoms, h2o, args.height, position=args.position, offset=args.offset)
71
- else:
72
- h2o = build.molecule('H2O')
73
- h2o.rotate(90, 'y')
74
- build.add_adsorbate(atoms, h2o, args.height, position=args.position, offset=args.offset)
75
- ## add H2Ob
76
- elif args.adsorbate in ['H2Ob']:
77
- h2o = build.molecule('H2O')
78
- h2o.rotate(90, 'z')
79
- h2o.rotate(45, 'y')
80
- build.add_adsorbate(atoms, h2o, args.height, position=args.position, offset=args.offset)
81
- ## add default something
13
+ @click.command(name='surface')
14
+ @click.argument('symbol', type=str)
15
+ @click.argument('surface', type=click.Choice(['fcc100', 'fcc110', 'fcc111', 'fcc211', 'bcc100', 'bcc110', 'bcc111', 'hcp0001', 'hcp10m10', 'diamond100', 'diamond111', 'mx2', 'graphene']))
16
+ @click.argument('size', type=click.Tuple([int, int, int]))
17
+ @click.option('--kind', type=click.Choice(['2H', '1T']), help='designate the kind of MX2 surface')
18
+ @click.option('-a', type=float, help='the lattice constant. if specified, it overrides the expermental lattice constant of the element. must be specified if setting up a crystal structure different from the one found in nature')
19
+ @click.option('-c', type=float, help='extra hcp lattice constant. if specified, it overrides the expermental lattice constant of the element. Default is ideal ratio: sqrt(8/3)', default=np.sqrt(8/3), show_default=True)
20
+ @click.option('--thickness', type=float, help='Thickness of the layer, for mx2 and graphene')
21
+ @click.option('--orth', is_flag=True, help='if specified and true, forces the creation of a unit cell with orthogonal basis vectors. if the default is such a unit cell, this argument is not supported')
22
+ @click.option('--vacuum', type=float, help='designate vacuum of surface, default is None', default=0.0)
23
+ def main(symbol, surface, size, kind, a, c, thickness, orth, vacuum, adsorbate):
24
+ #if args.primitive:
25
+ # a = args.a * 0.7071 * 2
26
+ #else:
27
+ # a = args.a
28
+
29
+ vacuum = vacuum / 2
30
+ build_surface = surface_check(build, surface)
31
+ out_filename = f"{symbol}_{surface}_{size[0]}{size[1]}{size[2]}_{adsorbate}.cif"
32
+
33
+ if surface in ['hcp0001', 'hcp10m10']:
34
+ atoms = build_surface(symbol, size, a=a, c=c, vacuum=vacuum, orthogonal=orth)
35
+ elif surface in ['mx2']:
36
+ if thickness is None:
37
+ atoms = build_surface(symbol, size, kind=kind, a=a, vacuum=vacuum)
82
38
  else:
83
- build.add_adsorbate(atoms, args.adsorbate, args.height, position=args.position, offset=args.offset)
84
-
85
- # add h with coverage
86
- if args.coverh != 0:
87
- ## get atom position at surface
88
- surface_positions_dict = {}
89
- for atom in atoms:
90
- if atom.tag == 1:
91
- surface_positions_dict[atom.index] = atom.position
92
- ## error checking
93
- if site_number := len(surface_positions_dict) < args.coverh:
94
- print(f"coverh is too big, please less then {site_number}")
95
- sys.exit()
96
- ## get random site
97
- random_site_list = np.random.choice(list(surface_positions_dict.keys()), args.coverh, replace=False)
98
- random_site_list = np.unique(random_site_list)
99
- ## add H atom at hollow site
100
- for site in random_site_list:
101
- site_position = surface_positions_dict[site][0:2]
102
- build.add_adsorbate(atoms, 'H', 2, position=site_position, offset=(0.3, 0.3))
39
+ atoms = build_surface(symbol, size, kind=kind, a=a, vacuum=vacuum, thickness=thickness)
40
+ elif surface in ['graphene']:
41
+ if a is None:
42
+ a = 2.46
103
43
 
104
- # control output format
105
- ## output with coord.xyz(cp2k format)
106
- if args.c:
107
- atoms.write('coord.xyz', format='xyz')
108
- with open('coord.xyz', 'r') as f:
109
- lines = f.readlines()[2:]
110
- with open('coord.xyz', 'w') as f:
111
- f.writelines(lines)
112
- with open('cell.inc', 'w') as f:
113
- cell = list(cell_to_cellpar(atoms.cell))
114
- f.write('ABC [angstrom] ' + str(cell[0]) + ' ' + str(cell[1]) + ' ' + str(cell[2]) + ' ' + '\n')
115
- f.write('ALPHA_BETA_GAMMA ' + str(cell[3]) + ' ' + str(cell[4]) + ' ' + str(cell[5]) + '\n')
116
- ## output kpoint file with specific number
117
- if args.k != None:
118
- if True: #judge M or G
119
- with open('kpoint.inc', 'w') as f:
120
- f.write(f"SCHEME MONKHORST-PACK {args.k[0]} {args.k[1]} {args.k[2]}" + "\n")
121
- ## output kpoint file autoly
122
- if args.autok:
123
- if True: # judge matel or semi or else
124
- if True: # judge M or G
125
- with open('kpoint.inc', 'w') as f:
126
- f.write(f"SCHEME MONKHORST-PACK {int(round(30/cell[0]))} {int(round(30/cell[1]))} {int(round(30/cell[2]))}" + "\n")
127
- ## output default format or specific xyz file
44
+ if thickness is None:
45
+ atoms = build_surface(formula=symbol, size=size, a=a, vacuum=vacuum)
46
+ else:
47
+ atoms = build_surface(formula=symbol, size=size, thickness=thickness, a=a, vacuum=vacuum)
128
48
  else:
129
- atoms.write(args.o)
49
+ atoms = build_surface(symbol, size, a=a, vacuum=vacuum, orthogonal=orth)
50
+
51
+ atoms.write(out_filename)
130
52
 
131
53
 
132
54
  if __name__ == '__main__':
mdkits/mdkits.py CHANGED
@@ -8,7 +8,7 @@ from mdkits.cli import (
8
8
  density,
9
9
  cube,
10
10
  pdos,
11
- build_bulk,
11
+ build_cli,
12
12
  )
13
13
 
14
14
 
@@ -16,7 +16,7 @@ from mdkits.cli import (
16
16
  @click.pass_context
17
17
  @click.version_option()
18
18
  def cli(ctx):
19
- """tools for md or dft"""
19
+ """kits for md or dft"""
20
20
  pass
21
21
 
22
22
 
@@ -28,7 +28,7 @@ cli.add_command(plot.main)
28
28
  cli.add_command(density.main)
29
29
  cli.add_command(cube.main)
30
30
  cli.add_command(pdos.main)
31
- cli.add_command(build_bulk.main)
31
+ cli.add_command(build_cli.cli_build)
32
32
 
33
33
 
34
34
  if __name__ == '__main__':
mdkits/util/arg_type.py CHANGED
@@ -37,5 +37,16 @@ class FrameRangeType(click.ParamType):
37
37
  self.fail(f"{value} is not a valid frame range", param, ctx)
38
38
 
39
39
 
40
+ from ase.collections import g2
41
+ class MoleculeType(click.Choice):
42
+ name = "mocular type"
43
+ def __init__(self):
44
+ super().__init__(self)
45
+ g2.names.append(click.Path(exists=True))
46
+ self.choices = tuple(g2.names)
47
+
48
+
49
+
40
50
  Cell = CellType()
41
51
  FrameRange = FrameRangeType()
52
+ Molecule = MoleculeType()
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mdkits
3
- Version: 0.1.4
4
- Summary: tools for md or dft
3
+ Version: 0.1.5
4
+ Summary: kits for md or dft
5
5
  License: MIT
6
6
  Keywords: molecular dynamics,density functional theory
7
7
  Author: jxxcr
@@ -98,8 +98,10 @@ mdkits cube [FILENAME] -b 1 2
98
98
  会将平均值打印在屏幕上, 同时记录在`cube.out`中的注释行.
99
99
 
100
100
  ## 建模
101
+ `build`为界面的工具, 其中包含多个建模工具
102
+
101
103
  ### 构建体相模型
102
- `build_bulk`用于构建体相模型, 如构建`Pt`的`fcc`体相模型:
104
+ `bulk`用于构建体相模型, 如构建`Pt`的`fcc`体相模型:
103
105
  ```bash
104
106
  mdkits build_bulk Pt fcc
105
107
  ```
@@ -116,6 +118,20 @@ mdkits build_bulk CsCl cesiumchloride -a 4.123
116
118
  mdkits build_bulk BaF2 fluorite -a 6.196
117
119
  ```
118
120
 
121
+ ### 构建表面模型
122
+ `surface`用于构建常见的表面模型, 骑用法为:
123
+ ```bash
124
+ mdkits build surface [ELEMENT] [SURFACE_TYPE] [SIZE]
125
+ ```
126
+ 如构建`Pt`的`fcc111`表面模型:
127
+ ```bash
128
+ mdkits build surface Pt fcc111 2 2 3 --vacuum 15
129
+ ```
130
+ 构建石墨烯表面:
131
+ ```bash
132
+ mdkits build surface C2 graphene 3 3 1 --vacuum 15
133
+ ```
134
+
119
135
  ## 其他
120
136
  ### 轨迹提取
121
137
  `extract`用于提取轨迹文件中的特定的帧, 如从`frames.xyz`中提取第 1000 帧到第 2000 帧的轨迹文件, 并输出为`1000-2000.xyz`, `-r`选项的参数与`Python`的切片语法一致:
@@ -1,9 +1,10 @@
1
1
  mdkits/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  "mdkits/cli/,hb_distribution_down.py",sha256=i3NguzGebqCgy4uuVBeFajZRZnXtjhsJBPDGDdumlWA,4733
3
- mdkits/cli/adsorbate.py,sha256=6PN6qVSzhOFLxjUal4T2Qk5W5XUWAUn5-JXS8-D0xqo,3126
4
- mdkits/cli/build_bulk.py,sha256=LJwC7IqDV_dY2cJJHwk9stqLu3wzbXxC87GMbyaalw0,1555
3
+ mdkits/cli/adsorbate.py,sha256=yC8YTdAYmt6NhsBR_PsIC14sPswMWcAJccxcDKx5fZY,3778
4
+ mdkits/cli/build_bulk.py,sha256=mOjoHHBui5fTYASabD96l6zBoKlQukT-LOyR2FZNzM4,1549
5
+ mdkits/cli/build_cli.py,sha256=ykxK2-fhOcbcPxQCBw9LKCh-Hkcj4Ke4iYbh3N6BJIk,325
5
6
  mdkits/cli/build_interface.py,sha256=i1YE5iwazKVsTdQ_DXalNYeA8oflORWFePgJin1AJM4,3537
6
- mdkits/cli/build_surface.py,sha256=tL9rSv6MROPRtVUu8JiPJbt4YdHFVKTZrEUaSd3rlzI,5657
7
+ mdkits/cli/build_surface.py,sha256=8-bAstqzPllkd9v-2bUzGlLQOgbOnfGg9MyTVRxFIVU,2641
7
8
  mdkits/cli/convert.py,sha256=s2q2Py7IVGNTctHgpHm66YFj_Rr8srnpuJudrMBI0oM,2014
8
9
  mdkits/cli/cube.py,sha256=G-QNup8W6J1-LCcEl1EHsV3nstd23byePDOcE_95t18,1176
9
10
  mdkits/cli/cut_surface.py,sha256=D1naCWj0QJE3AiInzy3SeGO37butothE3BS1rZsZ5MU,1425
@@ -21,9 +22,9 @@ mdkits/cli/supercell.py,sha256=r5iddLw1NNzj7NTFlR2j_jpD1AMfrsxhA08bPwQvVvg,2059
21
22
  mdkits/cli/wrap.py,sha256=AUxGISuiCfEjdMYl-TKc2VMCPHSybWKrMIOTn_6kSp0,1043
22
23
  mdkits/config/__init__.py,sha256=ZSwmnPK02LxJLMgcYmNb-tIOk8fEuHf5jpqD3SDHWLg,1039
23
24
  mdkits/config/settings.yml,sha256=PY7u0PbFLuxSnd54H5tI9oMjUf-mzyADqSZtm99BwG0,71
24
- mdkits/mdkits.py,sha256=cItenwSa9YWtd-YGg49l52VoIBDWqqeZmPIdx6LcqU0,601
25
+ mdkits/mdkits.py,sha256=ASOEhY94G_P902ojOobvqPYu1L3AOFTS_Ooh5LJAjX0,603
25
26
  mdkits/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- mdkits/util/arg_type.py,sha256=YUFhYShTYfUe7xajgUCiCuaeNLH-wxMXvlcMRax4zRM,1469
27
+ mdkits/util/arg_type.py,sha256=ZjP6_PKIEDnHk45ye7by4aKTeZzw1PJq3939jZw57hY,1743
27
28
  mdkits/util/cp2k_input_parsing.py,sha256=6BFVsbBYxdauaUPrjr5h8JXk_R0bu7V3cbG2DEWWFlQ,1291
28
29
  mdkits/util/encapsulated_ase.py,sha256=rmL80U3M8SsEU2M6QtLyiam2N1FIbrm5dK3P14p1EPg,4093
29
30
  mdkits/util/encapsulated_mda.py,sha256=td3H24u3eHOIS2nwPucfIaMxeaVxI77oFI8nnNhw7vo,2217
@@ -31,8 +32,8 @@ mdkits/util/fig_operation.py,sha256=FwffNUtXorMl6qE04FipgzcVljEQii7wrNJUCJMyY3E,
31
32
  mdkits/util/numpy_geo.py,sha256=1Op8THoQeyqybSZAi7hVxohYCr4SzY6ndZC8_gAGXDA,3619
32
33
  mdkits/util/os_operation.py,sha256=tNRjniDwFqARMy5Rf6MUNmaQGpJlyifCpuN16r8aB2g,828
33
34
  mdkits/util/structure_parsing.py,sha256=mRPMJeih3O-ST7HeETDvBEkfV-1psT-XgxyYgDadV0U,4152
34
- mdkits-0.1.4.dist-info/entry_points.txt,sha256=xoWWZ_yL87S501AzCO2ZjpnVuYkElC6z-8J3tmuIGXQ,44
35
- mdkits-0.1.4.dist-info/LICENSE,sha256=VLaqyB0r_H7y3hUntfpPWcE3OATTedHWI983htLftcQ,1081
36
- mdkits-0.1.4.dist-info/METADATA,sha256=i_qFaaji3Kb0FL8KGYaQPLHuhPhskcTM9pizTqIfeTE,6485
37
- mdkits-0.1.4.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
38
- mdkits-0.1.4.dist-info/RECORD,,
35
+ mdkits-0.1.5.dist-info/entry_points.txt,sha256=xoWWZ_yL87S501AzCO2ZjpnVuYkElC6z-8J3tmuIGXQ,44
36
+ mdkits-0.1.5.dist-info/LICENSE,sha256=VLaqyB0r_H7y3hUntfpPWcE3OATTedHWI983htLftcQ,1081
37
+ mdkits-0.1.5.dist-info/METADATA,sha256=egdGXbw2G_ZVtqF_Wj4Uhnc02wMKPAssXLiyW6-yyNM,6869
38
+ mdkits-0.1.5.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
39
+ mdkits-0.1.5.dist-info/RECORD,,
File without changes