几何优化

在本教程中,我们将展示如何使用MLatom优化分子的几何构型。这里只演示最小值的优化,过渡态的优化可在网页 教程 中查看

以下是使用XACS云计算平台和Python API进行几何优化的演示视频:

我们从最简单的例子开始,即使用输入文件 geomopt.inp 进行几何优化(使用Python API的例子请参见 后文):

geomopt                 # 1. requests geometry optimization
ANI-1ccx                # 2. pre-trained model
xyzfile=init.xyz        # 3. initial geometry guess
optxyz=opt.xyz          # 4. file with optimized geometry

输入文件非常直观,第一行表明任务类型, geometry 指几何优化。接下来,用户需要提供模型或方法,第二行表明使用机器学习势ANI-1ccx。原则上,任何量子力学方法、机器学习模型(预训练或由用户训练)或提供能量和梯度的QM/ML混合模型都可以使用( 后文 对此进行了说明)。

第三行 xyzfile=[file name] 告诉MLatom它可以在哪个文件中找到最初的几何构型猜测。用户应该在XYZ文件中提供初始猜测用于几何构型(以埃为单位,例如 init.xyz )例如乙醇的XYZ文件可以为:

9

C       -1.691449880     -0.315985130      0.000000000
H       -1.334777040      0.188413060      0.873651500
H       -1.334777040      0.188413060     -0.873651500
H       -2.761449880     -0.315971940      0.000000000
C       -1.178134160     -1.767917280      0.000000000
H       -1.534806620     -2.272315330      0.873651740
H       -1.534807450     -2.272316160     -0.873650920
O        0.251865840     -1.767934180     -0.000001150
H        0.572301420     -2.672876720      0.000175020

备注

这个不需要提供辅助文件的输入文件也可以运行:

ANI-1ccx                # pre-trained model
geomopt                 # requests geometry optimization
xyzfile='
9

C       -1.691449880     -0.315985130      0.000000000
H       -1.334777040      0.188413060      0.873651500
H       -1.334777040      0.188413060     -0.873651500
H       -2.761449880     -0.315971940      0.000000000
C       -1.178134160     -1.767917280      0.000000000
H       -1.534806620     -2.272315330      0.873651740
H       -1.534807450     -2.272316160     -0.873650920
O        0.251865840     -1.767934180     -0.000001150
H        0.572301420     -2.672876720      0.000175020
'

同样地, optxyz= 是可选的。如果用户没有指定此选项,则优化后的构型将保存到 optgeoms.xyz 文件中。

最后一行 optxyz=[文件名] 告诉MLatom将优化的几何构型保存在XYZ文件中(这里是 opt.xyz )。以上各行参数的顺序并不重要,除了文件名之外,各个参数不区分大小写。

在准备好输入文件和初始的XYZ文件后,就可以在MLatom上运行,以XACS云计算平台为例:

mlatom geomopt.inp &> geomopt.out

优化后的构型会以XYZ格式保存在 opt.xyz 中,程序的输出结果将保存在 geomopt.out 中。

或者,您可以在没有任何输入文件的情况下运行相同的模拟,只需要在命令行中使用相同的选项:

mlatom geomopt ANI-1ccx xyzfile=init.xyz optxyz=opt.xyz

用户可以在MLatom的输出文件中找到优化后的几何构型的属性,即ANI-1ccx方法中神经网络的最终能量和其他相关属性,例如标准差。此外,用户还可以检查优化过程,因为程序会打印出每个步骤的能量。对于上述例子,输出的部分为:

==============================================================================
Optimization of molecule 1
==============================================================================

...

------------------------------------------------------------------------------
Iteration 16
------------------------------------------------------------------------------

Molecule with 9 atom(s): C, H, H, H, C, H, H, O, H

XYZ coordinates, Angstrom

1    C            -1.672571          -0.341122          -0.000001
2    H            -1.307766           0.181713           0.885095
3    H            -1.307762           0.181707          -0.885099
4    H            -2.764560          -0.305014          -0.000003
5    C            -1.188732          -1.771664           0.000009
6    H            -1.559124          -2.298647           0.885998
7    H            -1.559099          -2.298653          -0.885987
8    O             0.237878          -1.729915           0.000028
9    H             0.575701          -2.626896           0.000135

Interatomic distance matrix, Angstrom

[[0.         1.09079523 1.09079553 1.09258554 1.51014856 2.15168963
2.15169099 2.3618975  3.20616369]
[1.09079523 0.         1.77019411 1.7727239  2.14784248 2.49306442
3.05812311 2.61279175 3.4955523 ]
[1.09079553 1.77019411 0.         1.77272412 2.14784559 3.05812426
2.49306137 2.61280479 3.49561397]
[1.09258554 1.7727239  1.77272412 0.         2.15274127 2.49251861
2.49252903 3.32339819 4.06798183]
[1.51014856 2.14784248 2.14784559 2.15274127 0.         1.09538946
1.09538987 1.42722094 1.96077669]
[2.15168963 2.49306442 3.05812426 2.49251861 1.09538946 0.
1.77198527 2.08269455 2.33451888]
[2.15169099 3.05812311 2.49306137 2.49252903 1.09538987 1.77198527
0.         2.08269348 2.33459306]
[2.3618975  2.61279175 2.61280479 3.32339819 1.42722094 2.08269455
2.08269348 0.         0.95848785]
[3.20616369 3.4955523  3.49561397 4.06798183 1.96077669 2.33451888
2.33459306 0.95848785 0.        ]]

Energy:        -154.891959 Hartree

Energy gradients, Hartree/Angstrom

1    C            -0.000084           0.000219           0.000000
2    H             0.000012          -0.000026          -0.000223
3    H             0.000012          -0.000025           0.000223
4    H             0.000084          -0.000248           0.000000
5    C             0.000027          -0.000139          -0.000001
6    H            -0.000370           0.000067           0.000512
7    H            -0.000371           0.000067          -0.000512
8    O             0.000601           0.000016          -0.000001
9    H             0.000089           0.000070           0.000001

Energy gradients norm:           0.001194 Hartree/Angstrom

Iteration         Energy (Hartree)
         1           -154.8894274342429
         2           -154.8894274342429
         3           -154.8913352129107
         4           -154.8915612759089
         5           -154.8917131295130
         6           -154.8917542901067
         7           -154.8918338589389
         8           -154.8918607356472
         9           -154.8918827332715
        10           -154.8919015405256
        11           -154.8919243290977
        12           -154.8919395989974
        13           -154.8919477894997
        14           -154.8919527832317
        15           -154.8919570330184
        16           -154.8919591168921


Final properties of molecule 1

Standard deviation of NNs                :      0.00063190 Hartree         0.39652 kcal/mol
Energy                                   :   -154.89195912 Hartree

用户的运行结果可能会有所不同,特别是取决于用户MLatom设置使用的优化器。上面的例子是使用带有L-BFGS优化器的ASE,它需要16次迭代才能收敛。

参阅下文有关 优化器 的介绍。

此外,几何优化会输出多个有用的文件:

  • 每个分子的优化轨迹保存在XYZ格式的 opttraj1.xyz 文件、JSON格式的 opttraj1.json 文件等。

  • 使用Gaussian优化器时,还会得到每个分子相应的输入和输出文件 gaussian1.comgaussian1.log

如果你想选择性保存信息(例如,对于大分子和许多分子的情况):

  • printmin 将不会输出每次迭代中的信息。

  • printall 将输出每次迭代中的详细信息。

  • dumpopttrajs=False 将不会输出任何优化轨迹。

选择方法或模型

MLatom中有许多方法或模型可用于几何优化。请参阅单独的手册和教程,这里我们提供简短的示例以帮助用户快速入门。如上所示,许多方法如ANI-1ccx或AIQM1都是由MLatom自动识别的。

定义QM方法仅需标明将要采用的方法和相应的QM程序(MLatom将使用这些程序的接口),例如从头算方法(例如HF或MP2)或DFT方法(例如B3LYP/6-31G*),如下所示:

geomopt                 # 1. requests geometry optimization
method=B3LYP/6-31G*     # 2. request running DFT optimization with B3LYP
qmprog=PySCF            # 3. request using PySCF for B3LYP calculations; qmprog=Gaussian can be also used
xyzfile=init.xyz        # 4. initial geometry guess
optxyz=opt.xyz          # 5. file with optimized geometry

如果要使用自定义的机器学习模型可以使用 MLmodelTypeMLmodelIn 关键字,例如:

geomopt                 # 1. requests geometry optimization
MLmodelType=MACE        # 2. request optimization with the MACE-type of machine learning potential
MLmodelIn=mace.pt       # 3. the file with the trained model should be provided, here it is mace.pt file
xyzfile=init.xyz        # 4. initial geometry guess
optxyz=opt.xyz          # 5. file with optimized geometry

关于如何训练此类模型,请参阅对应的手册和教程,例如 MACE

用户也可以自行定义混合模型(例如基于delta-learning概念的模型),但只能通过Python API实现(参见 后文的例子 )。

备注

原则上,我们的默认建议是使用AIQM1,因为在一定的计算成本下,它通常是最准确的方法。但目前AIQM1仅适用于含有CHON元素的化合物。另一个限制是为了使其更好地运行,我们建议为其QM部分安装MNDO程序。XACS云计算平台使用Sparrow,它目前只提供数值梯度,限制了它对几何优化的适用性。因此,使用ANI-1ccx是XACS云计算平台上的一个很好的替代方案(它对基态的中性闭壳层分子有额外的限制)

优化多个分子

MLatom作为一个面向数据的程序,可以对许多分子进行几何优化。用户只需准备XYZ文件,其中包含多个分子的初始猜测,例如在一个计算任务中同时优化氢气分子和甲烷分子,此时XYZ文件为:

2

1         0.0000000000        0.0000000000        0.0000000000
1         0.7414000000        0.0000000000        0.0000000000
5

C         0.0000000000        0.0000000000        0.0000000000
H         1.0870000000        0.0000000000        0.0000000000
H        -0.3623333220       -1.0248334322       -0.0000000000
H        -0.3623333220        0.5124167161       -0.8875317869
H        -0.3623333220        0.5124167161        0.8875317869

MLatom将在XYZ文件中保存优化的几何构型,其分子顺序与初始猜测中的顺序相同。输出也将包含每个分子的优化细节。

电荷和多重度

如果想定义单个或多个分子的电荷和多重性,以下输入文件可供参考:

geomopt                 # 1. requests geometry optimization
AIQM1                   # 2. AI-enhanced quantum mechanical method 1
xyzfile=init.xyz        # 3. initial geometry guess
optxyz=opt.xyz          # 4. file with optimized geometry
charges=0,1             # 5. charge of the first molecule is 0, of the second is 1.
multiplicities=1,2      # 6. multiplicity of the first molecule is 1, second - 2

备注

为 ANI-1ccx 等模型定义电荷和多重度是没有意义的,这些模型是在中性闭壳层分子上训练出来的。

选择优化程序

用户可以指定MLatom使用某个程序作为运行几何优化的优化器。如果您使用XACS云计算,它应该是ASE:

Atomic simulation environment (ASE):
A. Hjorth Larsen, et al. J. Phys. Condens. Matter.
2017, 29, 273002

备注

在输出文件中,MLatom将总结在您的出版物中使用的方法、模型和程序以及所推荐的引用。但是,通过Python API使用MLatom时不会输出,因此请仔细检查手册和引用的文章。

MLatom支持使用几种优化器:前面提到的ASE(使用L-BFGS算法),流行的Gaussian程序中的默认优化器,geomeTRIC(使用BFGS算法),以及SciPy中的优化器(默认使用L-BFGS算法)。它们可以通过添加 optprog=[ASE或Gaussian或SciPy] 关键字(不区分大小写)来选择,即:

geomopt                 # 1. requests geometry optimization
ANI-1ccx                # 2. pre-trained model
xyzfile=init.xyz        # 3. initial geometry guess
optxyz=opt.xyz          # 4. file with optimized geometry
optprog=gaussian        # 5. Gaussian is choosen as the optimizer

如果用户没有使用关键字来指定优化器,MLatom将检查各优化器的可用性并按照Gaussian -> ASE -> SciPy的顺序使用优化器。

每种优化器都有其优点和缺点:

  • ASE是开源的,并且已经经过测试。它可以在XACS云中使用,可以很容易地安装。

  • Gaussian是一个非常通用的程序,允许用户像往常一样使用其所有功能,并且能够访问ML模型。该程序应由用户单独获取并安装。目前的I/O效率并不高,因此使用ML模型进行优化将比使用其他优化器花费更长的时间。将来可能会得到改进。

  • geomeTRIC 也可使用。

  • 我们的SciPy还在测试当中,使用时需留意。

备注

MLatom正在不断更新,它将拥有更丰富的功能和更加优良的几何优化功能。我们的建议也会改变。请经常查看本教程,并关注我们的更新。

无论您选择哪种优化器,都建议查看下面的说明,以了解程序的不足和提示。

ASE优化器

ASE执行几何优化,直到达到定义的力阈值或最大迭代次数。最大迭代次数的默认值为200,力为0.02 eV/埃,默认算法为L-BFGS。这些默认值可以通过相应的ASE关键字来改变,例如:

geomopt                 # 1. requests geometry optimization
ANI-1ccx                # 2. pre-trained model
xyzfile=init.xyz        # 3. initial geometry guess
optxyz=opt.xyz          # 4. file with optimized geometry
optprog=ase             # 5. ASE is choosen as the optimizer
ase.steps=10000         # 6. increasing the maximum number of iterations from 200 to 10000
ase.fmax=0.01           # 7. tightening the convergence criterion from 0.02 to 0.01 eV/Angstrom
ase.optimizer=BFGS      # 8. selecting the BFGS instead of L-BFGS algorithm for optimization

备注

如果ASE优化器达到其最大优化迭代次数,MLatom将在最后一次迭代中保存最终的几何形状。请仔细检查MLatom的输出,如果迭代次数为200,此时的几何构型可能不是最优构型,需要重新进行优化。可以将优化步数 ase.steps 设置为更高的值,例如 ase.steps=10000

Gaussian优化器

当使用Gaussian优化器时,会产生与普通Gaussian输出文件相似的 gaussian.log 文件,不同之处在于,它将使用MLatom的模型来预测能量和梯度以执行几何优化。然后用户可以选用不同工具来分析这个输出,这对Gaussian用户来说是一个很大的优势。对于上面的例子,你可以检查MLatom的输出文件,使用Gaussian优化器进行上述几何优化:

==============================================================================
Optimization of molecule 1
==============================================================================

Iteration         Energy (Hartree)
            1           -154.8894274617628
            2           -154.8918239620292
            3           -154.8919507619391
            4           -154.8919601346281


Final properties of molecule 1

Standard deviation of NNs                :      0.00062817 Hartree         0.39419 kcal/mol
Energy                                   :   -154.89196013 Hartree

上述例子的完整 MLatom 输出文件和 Gaussian 输出文件也可以下载。

另一个重要的优点是,用户可以修改 gaussian.com 文件,该文件包含使用MLatom模型进行几何优化所需的输入。这样,用户就可以使用所有用于几何优化的Gaussian函数,如冻结坐标或在内部坐标中定义输入等。

在修改了 gaussian.com 文件之后,您可以像之前一样使用它运行Gaussian任务,例如,在您的系统中,在命令行中输入 g16 gaussian.com

使用Python API进行几何优化

对于许多用户来说,使用Python API进行几何优化可能更方便,因为它为使用更复杂的模型和构建提供了更大的灵活性。

下面是如何使用Python API进行上述所有模拟的例子。此外,我们将展示如何基于delta-learning构建更复杂的模型来执行几何优化。

首先,让我们优化乙醇的几何形状。代码如下:

import mlatom as ml

# Get the initial guess for the molecules to optimize
initmol = ml.data.molecule.from_xyz_file('init.xyz')
# initmol charge and multiplicity can be changed if required, e.g., by uncommenting the lines below:
#initmol.charge = 1 ; initmol.multiplicity = 2

# Choose one of the predifined (automatically recognized) methods
mymodel = ml.models.methods(method='ANI-1ccx')
# or QM method, e.g., B3LYP with Gaussian
#mymodel = ml.models.methods(method='B3LYP/6-31G*', program='Gaussian')
# or ML model, e.g., MACE:
#mymodel = ml.models.mace(model_file='mace.pt')

# Optimize the geometry with the choosen optimizer:
geomopt = ml.optimize_geometry(model=mymodel, initial_molecule=initmol, program='ASE', maximum_number_of_steps=10000)

# Get the final geometry
final_mol = geomopt.optimized_molecule
# and its XYZ coordinates
final_mol.xyz_coordinates

# Check and save the final geometry
print('Optimized coordinates:')
print(final_mol.get_xyz_string())
final_mol.write_file_with_xyz_coordinates(filename='final.xyz')

# You can also check the optimization trajectory
print('Number of optimization steps:', len(geomopt.optimization_trajectory.steps))
# and access any geometry during optimization as
intermediate_step_geom = geomopt.optimization_trajectory.steps[2].molecule
print('Intermediate coordinates:')
print(intermediate_step_geom.get_xyz_string())

注意这里有一个微小但很重要的区别:如果您使用 initial_molecule 参数,则initmol对象不会被更改,它将保持原来的初始分子。但是,如果您使用 molecule 参数,它将保存最终优化的坐标和其他属性(如力和能量)转化为初始的分子对象,即:

# This will not change the initmol, you can check it as
print('Initial molecule before optimization')
print(initmol.get_xyz_string())
geomopt = ml.optimize_geometry(model=mymodel, initial_molecule=initmol, program='ASE', maximum_number_of_steps=10000)
print('Initial molecule after optimization')
print(initmol.get_xyz_string())
print('Final coordinates after optimization')
print(geomopt.optimized_molecule.get_xyz_string())

# Compare to the following code that will change the initmol, you can check it as
print('Initial molecule before optimization')
print(initmol.get_xyz_string())
geomopt = ml.optimize_geometry(model=mymodel, molecule=initmol, program='ASE', maximum_number_of_steps=10000)
print('Initial molecule after optimization')
print(initmol.get_xyz_string())

第一种方法可以保留初始分子,第二种方法只保留最终的几何形状。

要运行上面的示例,您可能需要下载所需的文件( init.xyzmace.pt

自定义混合模型的优化

Here we show how to use a custom delta-learning model, trained on the differences between full configuration interaction and Hartree–Fock energies.

训练点的XYZ坐标、Full Cl能量和Hartree-Fock能量在教程压缩包中(xyz_h2_451.dat, E_FCI_451.dat, E_HF_451.dat)。用户可以尝试自己训练delta-learning模型。这里,我们提供了一个预训练的模型 delta_FCI-HF_h2.unf

import mlatom as ml

# Get the initial guess for the molecules to optimize
initmol = ml.data.molecule.from_xyz_file('h2_init.xyz')

# Let's build our own delta-model
# First, define the baseline QM method, e.g.,
baseline = ml.models.model_tree_node(name='baseline',
                                     operator='predict',
                                     model=ml.models.methods(method='HF/STO-3G',
                                                             program='pyscf'))
# Second, define the correcting ML model, in this case the KREG model trained on the differences between full CI and HF
delta_correction = ml.models.model_tree_node(name='delta_correction',
                                             operator='predict',
                                             model=ml.models.kreg(model_file='delta_FCI-HF_h2.unf',
                                                                  ml_program='MLatomF'))
# Third, build the delta-model which would sum up the predictions by the baseline (HF) with the correction from ML
delta_model = ml.models.model_tree_node(name='delta_model',
                                        children=[baseline, delta_correction],
                                        operator='sum')

# Optimize the geometry with the delta-model as usual:
geomopt = ml.optimize_geometry(model=delta_model, initial_molecule=initmol)

# Get the final geometry approximately at the full CI level
final_mol = geomopt.optimized_molecule
print('Optimized coordinates:')
print(final_mol.get_xyz_string())
final_mol.write_file_with_xyz_coordinates(filename='final.xyz')

# Let's check how many full CI calculations, our delta-model saved us
print('Number of optimization steps:', len(geomopt.optimization_trajectory.steps))

这个例子的灵感来自于我们书中关于 delta-learningkernel method potentials 的章节,模型的训练数据来自于 教程的章节

给定初始的几何构型 h2_init.xyz ,当使用上面的代码时,您将得到以下输出:

Optimized coordinates:
2

H             0.0000000000000          -0.0000000000000           0.3707890910739
H             0.0000000000000          -0.0000000000000          -0.3707890910739

Number of optimization steps: 4

自定义混合模型的优化

您还可以在几何优化过程中对分子进行约束。我们使用ASE实现,因此只有当您通过Python API使用ASE优化器时才可用。它还需要一个新的参数 constraints ,其使用方法为:constraints={'bonds':[[目标,[索引0,索引1]], ...],'angles':[[目标,[索引0,索引1,索引2]], ...],'dihedrals':[[目标,[索引0,索引1,索引2,索引3]], ...]} (请参阅 ASE中的FixInternals类 获取更多信息)。键长单位为埃,角和二面体的单位是度。注意,原子的指标从0开始!

备注

在MLatom 3.2.0版本中添加了约束优化

ASE在进行约束之前会检查优化收敛性,所以如果您以先前优化好的几何构型为初始猜测,可能会得到完全相同的几何构型。一种解决方案是稍微扰动初始几何构型。

下面是一个使用AIQM1优化乙烷的例子,将C-C键长目标设置为1.8埃。

初始的XYZ坐标为(ethane_initial.xyz):

8

C                 -3.41779278   -2.06081078    0.00000000
H                 -3.06113836   -3.06962078    0.00000000
H                 -3.06111994   -1.55641259   -0.87365150
H                 -4.48779278   -2.06079760    0.00000000
C                 -2.90445057   -1.33485451    1.25740497
H                 -1.83445237   -1.33656157    1.25838332
H                 -3.25950713   -0.32548149    1.25642758
H                 -3.26271953   -1.83812251    2.13105517

Python脚本为:

import mlatom as ml
mol = ml.data.molecule.from_xyz_file('ethane_initial.xyz')
print(f"Initial C-C bond length: {mol.get_internuclear_distance_matrix()[0][4]} Angstrom")
constraints = {'bonds':[[1.8,[0,4]]]}
aiqm1 = ml.models.methods(method='AIQM1',qm_program='sparrow')
geomopt = ml.optimize_geometry(model=aiqm1,initial_molecule=mol,program='ase',constraints=constraints)
optmol = geomopt.optimized_molecule
print(f"Final C-C bond length: {optmol.get_internuclear_distance_matrix()[0][4]} Angstrom")
print("XYZ coordinates:")
print(optmol.get_xyz_string())

输出如下所示:

Initial C-C bond length: 1.5399999964612658 Angstrom
       Step     Time          Energy         fmax
LBFGS:    0 10:11:55    -2169.358192        0.6954
LBFGS:    1 10:11:56    -2168.493055        1.5444
LBFGS:    2 10:11:56    -2168.324507        2.1746
LBFGS:    3 10:11:57    -2168.702277        0.3925
LBFGS:    4 10:11:57    -2168.719565        0.3556
LBFGS:    5 10:11:58    -2168.744194        0.4116
LBFGS:    6 10:11:58    -2168.765605        0.3914
LBFGS:    7 10:11:58    -2168.779525        0.2010
LBFGS:    8 10:11:59    -2168.782649        0.0282
LBFGS:    9 10:11:59    -2168.782767        0.0237
LBFGS:   10 10:12:00    -2168.782733        0.0370
LBFGS:   11 10:12:00    -2168.782749        0.0236
LBFGS:   12 10:12:00    -2168.782623        0.0873
LBFGS:   13 10:12:01    -2168.782774        0.0203
LBFGS:   14 10:12:01    -2168.782777        0.0217
LBFGS:   15 10:12:01    -2168.782654        0.0988
LBFGS:   16 10:12:02    -2168.782762        0.0299
LBFGS:   17 10:12:02    -2168.782723        0.0372
LBFGS:   18 10:12:03    -2168.782762        0.0250
LBFGS:   19 10:12:03    -2168.777521        0.5284
LBFGS:   20 10:12:03    -2168.782764        0.0369
LBFGS:   21 10:12:04    -2168.782758        0.0397
LBFGS:   22 10:12:04    -2168.781062        0.1423
LBFGS:   23 10:12:04    -2168.782774        0.0375
LBFGS:   24 10:12:05    -2168.782774        0.0251
LBFGS:   25 10:12:05    -2168.782670        0.0433
LBFGS:   26 10:12:06    -2168.782769        0.0209
LBFGS:   27 10:12:06    -2168.782777        0.0177
Final C-C bond length: 1.799999998386536 Angstrom
XYZ coordinates:
8

C            -3.4609594100000          -2.1223293000000          -0.1060679300000
H            -3.0827425100000          -3.1376804600000          -0.0751292200000
H            -3.0834089300000          -1.5865323800000          -0.9697472700000
H            -4.5445733300000          -2.1041917000000          -0.0741819000000
C            -2.8607234100000          -1.2737628100000           1.3635074000000
H            -1.7772071700000          -1.2935363400000           1.3338165800000
H            -3.2376294200000          -0.2576124300000           1.3304506900000
H            -3.2417292800000          -1.8070164100000           2.2269711900000

问题或建议

If you have further questions, criticism, and suggestions, we would be happy to receive them in English or Chinese via email, Slack (preferred), or QQ (135258964). See our contact page for more information on how to subscribe to updates and follow us on social media.