guohanghui commited on
Commit
07c1785
·
verified ·
1 Parent(s): e049815

Update atomman/mcp_output/mcp_plugin/mcp_service.py

Browse files
atomman/mcp_output/mcp_plugin/mcp_service.py CHANGED
@@ -1,261 +1,124 @@
1
  from fastmcp import FastMCP
2
- import numpy as np
3
 
4
  # Create the FastMCP service application
5
  mcp = FastMCP("atomman_service")
6
 
7
-
8
- @mcp.tool(name="create_atoms", description="Create an Atoms object and return its properties")
9
- def create_atoms(positions: list, symbols: list) -> dict:
10
- """
11
- Create an Atoms object.
12
-
13
- Parameters:
14
- - positions: List of atomic positions, e.g. [[0,0,0], [0.5,0.5,0.5]].
15
- - symbols: List of atomic symbols, e.g. ['Fe', 'Fe'].
16
-
17
- Returns:
18
- - Dictionary with success status and atoms information.
19
- """
20
- try:
21
- from atomman.core import Atoms
22
- atoms = Atoms(positions=positions, symbols=symbols)
23
- return {
24
- "success": True,
25
- "natoms": atoms.natoms,
26
- "symbols": list(atoms.symbols),
27
- "positions": atoms.pos.tolist()
28
- }
29
- except Exception as e:
30
- return {"success": False, "error": str(e)}
31
-
32
-
33
- @mcp.tool(name="create_box", description="Create a simulation box")
34
- def create_box(vects: list) -> dict:
35
- """
36
- Create a Box object.
37
-
38
- Parameters:
39
- - vects: 3x3 list of box vectors, e.g. [[10,0,0], [0,10,0], [0,0,10]].
40
-
41
- Returns:
42
- - Dictionary with success status and box information.
43
  """
44
- try:
45
- from atomman.core import Box
46
- box = Box(vects=vects)
47
- return {
48
- "success": True,
49
- "vects": box.vects.tolist(),
50
- "a": float(box.a),
51
- "b": float(box.b),
52
- "c": float(box.c),
53
- "alpha": float(box.alpha),
54
- "beta": float(box.beta),
55
- "gamma": float(box.gamma),
56
- "volume": float(box.volume)
57
- }
58
- except Exception as e:
59
- return {"success": False, "error": str(e)}
60
-
61
-
62
- @mcp.tool(name="calculate_elastic_constants", description="Calculate elastic constants from Cij matrix")
63
- def calculate_elastic_constants(Cij: list) -> dict:
64
- """
65
- Calculate elastic constants.
66
 
67
  Parameters:
68
- - Cij: 6x6 elastic stiffness matrix in Voigt notation (GPa).
69
 
70
  Returns:
71
- - Dictionary with success status and elastic properties.
72
  """
73
  try:
74
- from atomman.core import ElasticConstants
75
- elastic = ElasticConstants(Cij=np.array(Cij))
76
- return {
77
- "success": True,
78
- "Cij": elastic.Cij.tolist(),
79
- "Sij": elastic.Sij.tolist(),
80
- "bulk_modulus": float(elastic.bulk()),
81
- "shear_modulus": float(elastic.shear())
82
- }
83
- except Exception as e:
84
- return {"success": False, "error": str(e)}
85
-
86
-
87
- @mcp.tool(name="create_system", description="Create an atomic system with atoms and box")
88
- def create_system(positions: list, symbols: list, box_vects: list) -> dict:
89
- """
90
- Create a System object combining atoms and box.
91
-
92
- Parameters:
93
- - positions: List of atomic positions, e.g. [[0,0,0], [0.5,0.5,0.5]].
94
- - symbols: List of atomic symbols, e.g. ['Fe', 'Fe'].
95
- - box_vects: 3x3 list of box vectors, e.g. [[10,0,0], [0,10,0], [0,0,10]].
96
-
97
- Returns:
98
- - Dictionary with success status and system information.
99
- """
100
- try:
101
- from atomman.core import Atoms, Box, System
102
- atoms = Atoms(positions=positions, symbols=symbols)
103
- box = Box(vects=box_vects)
104
- system = System(atoms=atoms, box=box)
105
  return {
106
  "success": True,
107
- "natoms": system.natoms,
108
- "symbols": list(system.symbols),
109
- "box_volume": float(system.box.volume),
110
- "density": float(system.natoms / system.box.volume)
111
  }
112
  except Exception as e:
113
  return {"success": False, "error": str(e)}
114
 
115
-
116
- @mcp.tool(name="calculate_miller_indices", description="Convert vectors to Miller indices")
117
- def calculate_miller_indices(vectors: list) -> dict:
118
  """
119
- Calculate Miller indices from crystallographic vectors.
120
 
121
  Parameters:
122
- - vectors: List of vectors to convert, e.g. [[1,1,0], [1,1,1]].
 
123
 
124
  Returns:
125
- - Dictionary with success status and Miller indices.
126
  """
127
  try:
128
- from atomman.tools import miller
129
- indices = miller.vector_crystal_to_cartesian(np.array(vectors))
 
 
 
130
  return {
131
  "success": True,
132
- "miller_indices": indices.tolist() if hasattr(indices, 'tolist') else list(indices)
133
  }
134
  except Exception as e:
135
  return {"success": False, "error": str(e)}
136
 
137
-
138
- @mcp.tool(name="calculate_vector_angle", description="Calculate angle between two vectors")
139
- def calculate_vector_angle(vector1: list, vector2: list) -> dict:
140
  """
141
- Calculate angle between two vectors.
142
 
143
  Parameters:
144
- - vector1: First vector, e.g. [1, 0, 0].
145
- - vector2: Second vector, e.g. [0, 1, 0].
146
 
147
  Returns:
148
- - Dictionary with success status and angle in degrees.
149
  """
150
  try:
151
- from atomman.tools import vect_angle
152
- angle = vect_angle(vector1, vector2)
 
 
153
  return {
154
  "success": True,
155
- "angle_degrees": float(angle)
156
  }
157
  except Exception as e:
158
  return {"success": False, "error": str(e)}
159
 
160
-
161
- @mcp.tool(name="load_lammps_dump", description="Load atomic structure from LAMMPS dump file content")
162
- def load_lammps_dump(dump_content: str) -> dict:
163
  """
164
- Parse LAMMPS dump file content.
165
 
166
  Parameters:
167
- - dump_content: String content of a LAMMPS dump file.
 
168
 
169
  Returns:
170
- - Dictionary with success status and structure information.
171
  """
172
  try:
173
- import atomman as am
174
- import tempfile
175
- import os
176
-
177
- # Write content to temp file
178
- with tempfile.NamedTemporaryFile(mode='w', suffix='.dump', delete=False) as f:
179
- f.write(dump_content)
180
- temp_path = f.name
181
 
182
- try:
183
- system = am.load('atom_dump', temp_path)
184
- result = {
185
- "success": True,
186
- "natoms": system.natoms,
187
- "box_volume": float(system.box.volume)
188
- }
189
- finally:
190
- os.unlink(temp_path)
191
-
192
- return result
193
- except Exception as e:
194
- return {"success": False, "error": str(e)}
195
-
196
-
197
- @mcp.tool(name="rotate_system", description="Rotate an atomic system")
198
- def rotate_system(positions: list, symbols: list, box_vects: list, rotation_matrix: list) -> dict:
199
- """
200
- Rotate an atomic system by a rotation matrix.
201
-
202
- Parameters:
203
- - positions: List of atomic positions.
204
- - symbols: List of atomic symbols.
205
- - box_vects: 3x3 list of box vectors.
206
- - rotation_matrix: 3x3 rotation matrix.
207
-
208
- Returns:
209
- - Dictionary with rotated system information.
210
- """
211
- try:
212
- from atomman.core import Atoms, Box, System
213
- atoms = Atoms(positions=positions, symbols=symbols)
214
- box = Box(vects=box_vects)
215
- system = System(atoms=atoms, box=box)
216
 
217
- rotated = system.rotate(np.array(rotation_matrix))
218
  return {
219
  "success": True,
220
- "natoms": rotated.natoms,
221
- "positions": rotated.atoms.pos.tolist(),
222
- "box_vects": rotated.box.vects.tolist()
223
  }
224
  except Exception as e:
225
  return {"success": False, "error": str(e)}
226
 
227
-
228
- @mcp.tool(name="calculate_neighbor_list", description="Calculate neighbor list for atoms")
229
- def calculate_neighbor_list(positions: list, symbols: list, box_vects: list, cutoff: float) -> dict:
230
  """
231
- Calculate neighbor list for an atomic system.
232
 
233
  Parameters:
234
- - positions: List of atomic positions.
235
- - symbols: List of atomic symbols.
236
- - box_vects: 3x3 list of box vectors.
237
- - cutoff: Cutoff distance for neighbors.
238
 
239
  Returns:
240
- - Dictionary with neighbor information.
241
  """
242
  try:
243
- from atomman.core import Atoms, Box, System
244
- atoms = Atoms(positions=positions, symbols=symbols)
245
- box = Box(vects=box_vects)
246
- system = System(atoms=atoms, box=box)
247
-
248
- neighbors = system.neighborlist(cutoff=cutoff)
249
 
250
- # Get coordination numbers
251
- coord_numbers = [len(neighbors[i]) for i in range(system.natoms)]
252
 
253
  return {
254
  "success": True,
255
- "natoms": system.natoms,
256
- "cutoff": cutoff,
257
- "coordination_numbers": coord_numbers,
258
- "average_coordination": float(np.mean(coord_numbers))
259
  }
260
  except Exception as e:
261
  return {"success": False, "error": str(e)}
@@ -265,6 +128,6 @@ def create_app() -> FastMCP:
265
  Create and return the FastMCP application instance.
266
 
267
  Returns:
268
- - FastMCP instance.
269
  """
270
  return mcp
 
1
  from fastmcp import FastMCP
 
2
 
3
  # Create the FastMCP service application
4
  mcp = FastMCP("atomman_service")
5
 
6
+ @mcp.tool(name="list_lattice_parameters", description="List lattice parameters of a crystal structure")
7
+ def list_lattice_parameters(lattice: dict) -> dict:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  """
9
+ List the lattice parameters of a given crystal structure.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  Parameters:
12
+ - lattice: A dictionary containing lattice vectors and angles.
13
 
14
  Returns:
15
+ - dict: Lattice parameters including a, b, c, alpha, beta, gamma.
16
  """
17
  try:
18
+ from atomman.lattice import Lattice
19
+
20
+ lattice_obj = Lattice(**lattice)
21
+ params = lattice_obj.parameters()
22
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  return {
24
  "success": True,
25
+ "parameters": params
 
 
 
26
  }
27
  except Exception as e:
28
  return {"success": False, "error": str(e)}
29
 
30
+ @mcp.tool(name="calculate_displacement", description="Calculate atomic displacements in a system")
31
+ def calculate_displacement(system: dict, displacements: list) -> dict:
 
32
  """
33
+ Calculate atomic displacements in a system.
34
 
35
  Parameters:
36
+ - system: A dictionary representing the atomic system.
37
+ - displacements: A list of displacement vectors.
38
 
39
  Returns:
40
+ - dict: Updated atomic positions after applying displacements.
41
  """
42
  try:
43
+ from atomman import System
44
+
45
+ system_obj = System(**system)
46
+ system_obj.displace(displacements)
47
+
48
  return {
49
  "success": True,
50
+ "updated_positions": system_obj.atoms.pos
51
  }
52
  except Exception as e:
53
  return {"success": False, "error": str(e)}
54
 
55
+ @mcp.tool(name="compute_elastic_constants", description="Compute elastic constants of a material")
56
+ def compute_elastic_constants(system: dict, strain: dict) -> dict:
 
57
  """
58
+ Compute the elastic constants of a material.
59
 
60
  Parameters:
61
+ - system: A dictionary representing the atomic system.
62
+ - strain: A dictionary representing the strain tensor.
63
 
64
  Returns:
65
+ - dict: Elastic constants of the material.
66
  """
67
  try:
68
+ from atomman import ElasticConstants
69
+
70
+ elastic_constants = ElasticConstants(**strain)
71
+
72
  return {
73
  "success": True,
74
+ "elastic_constants": elastic_constants.C
75
  }
76
  except Exception as e:
77
  return {"success": False, "error": str(e)}
78
 
79
+ @mcp.tool(name="generate_crystal_structure", description="Generate a crystal structure from lattice and basis")
80
+ def generate_crystal_structure(lattice: dict, basis: list) -> dict:
 
81
  """
82
+ Generate a crystal structure from lattice parameters and basis atoms.
83
 
84
  Parameters:
85
+ - lattice: A dictionary containing lattice vectors and angles.
86
+ - basis: A list of basis atoms with positions.
87
 
88
  Returns:
89
+ - dict: Generated crystal structure.
90
  """
91
  try:
92
+ from atomman import System
 
 
 
 
 
 
 
93
 
94
+ system = System(lattice=lattice, atoms=basis)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
 
96
  return {
97
  "success": True,
98
+ "system": system.dump('json')
 
 
99
  }
100
  except Exception as e:
101
  return {"success": False, "error": str(e)}
102
 
103
+ @mcp.tool(name="analyze_vacancies", description="Analyze vacancies in a crystal structure")
104
+ def analyze_vacancies(system: dict) -> dict:
 
105
  """
106
+ Analyze vacancies in a crystal structure.
107
 
108
  Parameters:
109
+ - system: A dictionary representing the atomic system.
 
 
 
110
 
111
  Returns:
112
+ - dict: Information about vacancies in the structure.
113
  """
114
  try:
115
+ from atomman.defect import Vacancy
 
 
 
 
 
116
 
117
+ vacancy = Vacancy(system)
 
118
 
119
  return {
120
  "success": True,
121
+ "vacancies": vacancy.vacancies
 
 
 
122
  }
123
  except Exception as e:
124
  return {"success": False, "error": str(e)}
 
128
  Create and return the FastMCP application instance.
129
 
130
  Returns:
131
+ - FastMCP: The FastMCP application instance.
132
  """
133
  return mcp