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.

angle.py 8.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. """angle 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 Angle(nn.Cell):
  21. """Angle class"""
  22. def __init__(self, controller):
  23. super(Angle, self).__init__()
  24. if controller.amber_parm is not None:
  25. file_path = controller.amber_parm
  26. self.read_information_from_amberfile(file_path)
  27. self.atom_a = Tensor(np.asarray(self.h_atom_a, np.int32), mstype.int32)
  28. self.atom_b = Tensor(np.asarray(self.h_atom_b, np.int32), mstype.int32)
  29. self.atom_c = Tensor(np.asarray(self.h_atom_c, np.int32), mstype.int32)
  30. self.angle_k = Tensor(np.asarray(self.h_angle_k, np.float32), mstype.float32)
  31. self.angle_theta0 = Tensor(np.asarray(self.h_angle_theta0, np.float32), mstype.float32)
  32. def read_process1(self, context):
  33. """read_information_from_amberfile process1"""
  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.angle_with_H_numbers = value[4]
  41. self.angle_without_H_numbers = value[5]
  42. self.angle_numbers = self.angle_with_H_numbers + self.angle_without_H_numbers
  43. information = []
  44. information.extend(value)
  45. while count < 15:
  46. start_idx += 1
  47. value = list(map(int, context[start_idx].strip().split()))
  48. information.extend(value)
  49. count += len(value)
  50. self.angle_type_numbers = information[16]
  51. print("angle type numbers ", self.angle_type_numbers)
  52. break
  53. def read_process2(self, context):
  54. """read_information_from_amberfile process2"""
  55. angle_count = 0
  56. for idx, val in enumerate(context):
  57. if "%FLAG ANGLES_INC_HYDROGEN" in val:
  58. count = 0
  59. start_idx = idx
  60. information = []
  61. while count < 4 * self.angle_with_H_numbers:
  62. start_idx += 1
  63. if "%FORMAT" in context[start_idx]:
  64. continue
  65. else:
  66. value = list(map(int, context[start_idx].strip().split()))
  67. information.extend(value)
  68. count += len(value)
  69. for _ in range(self.angle_with_H_numbers):
  70. self.h_atom_a[angle_count] = information[angle_count * 4 + 0] / 3
  71. self.h_atom_b[angle_count] = information[angle_count * 4 + 1] / 3
  72. self.h_atom_c[angle_count] = information[angle_count * 4 + 2] / 3
  73. self.h_type[angle_count] = information[angle_count * 4 + 3] - 1
  74. angle_count += 1
  75. break
  76. return angle_count
  77. def read_information_from_amberfile(self, file_path):
  78. """read information from amberfile"""
  79. file = open(file_path, 'r')
  80. context = file.readlines()
  81. file.close()
  82. self.read_process1(context)
  83. self.h_atom_a = [0] * self.angle_numbers
  84. self.h_atom_b = [0] * self.angle_numbers
  85. self.h_atom_c = [0] * self.angle_numbers
  86. self.h_type = [0] * self.angle_numbers
  87. angle_count = self.read_process2(context)
  88. for idx, val in enumerate(context):
  89. if "%FLAG ANGLES_WITHOUT_HYDROGEN" in val:
  90. count = 0
  91. start_idx = idx
  92. information = []
  93. while count < 4 * self.angle_without_H_numbers:
  94. start_idx += 1
  95. if "%FORMAT" in context[start_idx]:
  96. continue
  97. else:
  98. value = list(map(int, context[start_idx].strip().split()))
  99. information.extend(value)
  100. count += len(value)
  101. for i in range(self.angle_without_H_numbers):
  102. self.h_atom_a[angle_count] = information[(angle_count - self.angle_with_H_numbers) * 4 + 0] / 3
  103. self.h_atom_b[angle_count] = information[(angle_count - self.angle_with_H_numbers) * 4 + 1] / 3
  104. self.h_atom_c[angle_count] = information[(angle_count - self.angle_with_H_numbers) * 4 + 2] / 3
  105. self.h_type[angle_count] = information[(angle_count - self.angle_with_H_numbers) * 4 + 3] - 1
  106. angle_count += 1
  107. break
  108. self.type_k = [0] * self.angle_type_numbers
  109. for idx, val in enumerate(context):
  110. if "%FLAG ANGLE_FORCE_CONSTANT" in val:
  111. count = 0
  112. start_idx = idx
  113. information = []
  114. while count < self.angle_type_numbers:
  115. start_idx += 1
  116. if "%FORMAT" in context[start_idx]:
  117. continue
  118. else:
  119. # print(start_idx)
  120. value = list(map(float, context[start_idx].strip().split()))
  121. information.extend(value)
  122. count += len(value)
  123. self.type_k = information[:self.angle_type_numbers]
  124. break
  125. self.type_theta0 = [0] * self.angle_type_numbers
  126. for idx, val in enumerate(context):
  127. if "%FLAG ANGLE_EQUIL_VALUE" in val:
  128. count = 0
  129. start_idx = idx
  130. information = []
  131. while count < self.angle_type_numbers:
  132. start_idx += 1
  133. if "%FORMAT" in context[start_idx]:
  134. continue
  135. else:
  136. value = list(map(float, context[start_idx].strip().split()))
  137. information.extend(value)
  138. count += len(value)
  139. self.type_theta0 = information[:self.angle_type_numbers]
  140. break
  141. if self.angle_numbers != angle_count:
  142. print("angle count %d != angle_number %d ", angle_count, self.angle_numbers)
  143. self.h_angle_k = []
  144. self.h_angle_theta0 = []
  145. for i in range(self.angle_numbers):
  146. self.h_angle_k.append(self.type_k[self.h_type[i]])
  147. self.h_angle_theta0.append(self.type_theta0[self.h_type[i]])
  148. def Angle_Energy(self, uint_crd, uint_dr_to_dr_cof):
  149. """compute angle energy"""
  150. self.angle_energy = P.AngleEnergy(self.angle_numbers)(uint_crd, uint_dr_to_dr_cof, self.atom_a, self.atom_b,
  151. self.atom_c, self.angle_k, self.angle_theta0)
  152. self.sigma_of_angle_ene = P.ReduceSum()(self.angle_energy)
  153. return self.sigma_of_angle_ene
  154. def Angle_Force_With_Atom_Energy(self, uint_crd, scaler):
  155. """compute angle force with atom energy"""
  156. print("angele angle numbers:", self.angle_numbers)
  157. self.afae = P.AngleForceWithAtomEnergy(angle_numbers=self.angle_numbers)
  158. frc, ene = self.afae(uint_crd, scaler, self.atom_a, self.atom_b, self.atom_c, self.angle_k, self.angle_theta0)
  159. return frc, ene