You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

bond.py 7.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. # Copyright 2021 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ============================================================================
  15. """bond class"""
  16. import numpy as np
  17. import mindspore.common.dtype as mstype
  18. from mindspore import Tensor, nn
  19. from mindspore.ops import operations as P
  20. class Bond(nn.Cell):
  21. """bond class"""
  22. def __init__(self, controller, md_info):
  23. super(Bond, self).__init__()
  24. self.atom_numbers = md_info.atom_numbers
  25. if controller.amber_parm is not None:
  26. file_path = controller.amber_parm
  27. self.read_information_from_amberfile(file_path)
  28. self.atom_a = Tensor(np.asarray(self.h_atom_a, np.int32), mstype.int32)
  29. self.atom_b = Tensor(np.asarray(self.h_atom_b, np.int32), mstype.int32)
  30. self.bond_k = Tensor(np.asarray(self.h_k, np.float32), mstype.float32)
  31. self.bond_r0 = Tensor(np.asarray(self.h_r0, np.float32), mstype.float32)
  32. def process1(self, context):
  33. """process1: read information from amberfile"""
  34. for idx, val in enumerate(context):
  35. if idx < len(context) - 1:
  36. if "%FLAG POINTERS" in val + context[idx + 1] and "%FORMAT(10I8)" in val + context[idx + 1]:
  37. start_idx = idx + 2
  38. count = 0
  39. value = list(map(int, context[start_idx].strip().split()))
  40. self.bond_with_hydrogen = value[2]
  41. self.bond_numbers = value[3]
  42. self.bond_numbers += self.bond_with_hydrogen
  43. print(self.bond_numbers)
  44. information = []
  45. information.extend(value)
  46. while count < 16:
  47. start_idx += 1
  48. value = list(map(int, context[start_idx].strip().split()))
  49. information.extend(value)
  50. count += len(value)
  51. self.bond_type_numbers = information[15]
  52. print("bond type numbers ", self.bond_type_numbers)
  53. break
  54. for idx, val in enumerate(context):
  55. if "%FLAG BOND_FORCE_CONSTANT" in val:
  56. count = 0
  57. start_idx = idx
  58. information = []
  59. while count < self.bond_type_numbers:
  60. start_idx += 1
  61. if "%FORMAT" in context[start_idx]:
  62. continue
  63. else:
  64. value = list(map(float, context[start_idx].strip().split()))
  65. information.extend(value)
  66. count += len(value)
  67. self.bond_type_k = information[:self.bond_type_numbers]
  68. break
  69. def read_information_from_amberfile(self, file_path):
  70. """read information from amberfile"""
  71. file = open(file_path, 'r')
  72. context = file.readlines()
  73. file.close()
  74. self.process1(context)
  75. for idx, val in enumerate(context):
  76. if "%FLAG BOND_EQUIL_VALUE" in val:
  77. count = 0
  78. start_idx = idx
  79. information = []
  80. while count < self.bond_type_numbers:
  81. start_idx += 1
  82. if "%FORMAT" in context[start_idx]:
  83. continue
  84. else:
  85. value = list(map(float, context[start_idx].strip().split()))
  86. information.extend(value)
  87. count += len(value)
  88. self.bond_type_r = information[:self.bond_type_numbers]
  89. break
  90. for idx, val in enumerate(context):
  91. if "%FLAG BONDS_INC_HYDROGEN" in val:
  92. self.h_atom_a = [0] * self.bond_numbers
  93. self.h_atom_b = [0] * self.bond_numbers
  94. self.h_k = [0] * self.bond_numbers
  95. self.h_r0 = [0] * self.bond_numbers
  96. count = 0
  97. start_idx = idx
  98. information = []
  99. while count < 3 * self.bond_with_hydrogen:
  100. start_idx += 1
  101. if "%FORMAT" in context[start_idx]:
  102. continue
  103. else:
  104. value = list(map(int, context[start_idx].strip().split()))
  105. information.extend(value)
  106. count += len(value)
  107. for i in range(self.bond_with_hydrogen):
  108. self.h_atom_a[i] = information[3 * i + 0] / 3
  109. self.h_atom_b[i] = information[3 * i + 1] / 3
  110. tmpi = information[3 * i + 2] - 1
  111. self.h_k[i] = self.bond_type_k[tmpi]
  112. self.h_r0[i] = self.bond_type_r[tmpi]
  113. break
  114. for idx, val in enumerate(context):
  115. if "%FLAG BONDS_WITHOUT_HYDROGEN" in val:
  116. count = 0
  117. start_idx = idx
  118. information = []
  119. while count < 3 * (self.bond_numbers - self.bond_with_hydrogen):
  120. start_idx += 1
  121. if "%FORMAT" in context[start_idx]:
  122. continue
  123. else:
  124. value = list(map(int, context[start_idx].strip().split()))
  125. information.extend(value)
  126. count += len(value)
  127. for i in range(self.bond_with_hydrogen, self.bond_numbers):
  128. self.h_atom_a[i] = information[3 * (i - self.bond_with_hydrogen) + 0] / 3
  129. self.h_atom_b[i] = information[3 * (i - self.bond_with_hydrogen) + 1] / 3
  130. tmpi = information[3 * (i - self.bond_with_hydrogen) + 2] - 1
  131. self.h_k[i] = self.bond_type_k[tmpi]
  132. self.h_r0[i] = self.bond_type_r[tmpi]
  133. break
  134. def Bond_Energy(self, uint_crd, uint_dr_to_dr_cof):
  135. """compute bond energy"""
  136. self.bond_energy = P.BondEnergy(self.bond_numbers, self.atom_numbers)(uint_crd, uint_dr_to_dr_cof, self.atom_a,
  137. self.atom_b, self.bond_k, self.bond_r0)
  138. self.sigma_of_bond_ene = P.ReduceSum()(self.bond_energy)
  139. return self.sigma_of_bond_ene
  140. def Bond_Force_With_Atom_Energy(self, uint_crd, scaler):
  141. """compute bond force with atom energy"""
  142. self.bfatomenergy = P.BondForceWithAtomEnergy(bond_numbers=self.bond_numbers,
  143. atom_numbers=self.atom_numbers)
  144. frc, atom_energy = self.bfatomenergy(uint_crd, scaler, self.atom_a, self.atom_b, self.bond_k, self.bond_r0)
  145. return frc, atom_energy