ltbams 0.9.9__py3-none-any.whl → 1.0.0__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.
Files changed (728) hide show
  1. ams/__init__.py +4 -11
  2. ams/_version.py +4 -4
  3. ams/cases/5bus/pjm5bus_demo.xlsx +0 -0
  4. ams/cases/5bus/pjm5bus_jumper.xlsx +0 -0
  5. ams/cases/5bus/pjm5bus_uced.json +1062 -0
  6. ams/cases/5bus/pjm5bus_uced.xlsx +0 -0
  7. ams/cases/5bus/pjm5bus_uced_esd1.xlsx +0 -0
  8. ams/cases/5bus/pjm5bus_uced_ev.xlsx +0 -0
  9. ams/cases/ieee123/ieee123.xlsx +0 -0
  10. ams/cases/ieee123/ieee123_regcv1.xlsx +0 -0
  11. ams/cases/ieee14/ieee14.json +1166 -0
  12. ams/cases/ieee14/ieee14.raw +92 -0
  13. ams/cases/ieee14/ieee14_conn.xlsx +0 -0
  14. ams/cases/ieee14/ieee14_uced.xlsx +0 -0
  15. ams/cases/ieee39/ieee39.xlsx +0 -0
  16. ams/cases/ieee39/ieee39_uced.xlsx +0 -0
  17. ams/cases/ieee39/ieee39_uced_esd1.xlsx +0 -0
  18. ams/cases/ieee39/ieee39_uced_pvd1.xlsx +0 -0
  19. ams/cases/ieee39/ieee39_uced_vis.xlsx +0 -0
  20. ams/cases/matpower/benchmark.json +1594 -0
  21. ams/cases/matpower/case118.m +787 -0
  22. ams/cases/matpower/case14.m +129 -0
  23. ams/cases/matpower/case300.m +1315 -0
  24. ams/cases/matpower/case39.m +205 -0
  25. ams/cases/matpower/case5.m +62 -0
  26. ams/cases/matpower/case_ACTIVSg2000.m +9460 -0
  27. ams/cases/npcc/npcc.m +644 -0
  28. ams/cases/npcc/npcc_uced.xlsx +0 -0
  29. ams/cases/pglib/pglib_opf_case39_epri__api.m +243 -0
  30. ams/cases/wecc/wecc.m +714 -0
  31. ams/cases/wecc/wecc_uced.xlsx +0 -0
  32. ams/cli.py +6 -0
  33. ams/core/__init__.py +2 -0
  34. ams/core/documenter.py +652 -0
  35. ams/core/matprocessor.py +782 -0
  36. ams/core/model.py +330 -0
  37. ams/core/param.py +322 -0
  38. ams/core/service.py +918 -0
  39. ams/core/symprocessor.py +224 -0
  40. ams/core/var.py +59 -0
  41. ams/extension/__init__.py +5 -0
  42. ams/extension/eva.py +401 -0
  43. ams/interface.py +1085 -0
  44. ams/io/__init__.py +133 -0
  45. ams/io/json.py +82 -0
  46. ams/io/matpower.py +406 -0
  47. ams/io/psse.py +6 -0
  48. ams/io/pypower.py +103 -0
  49. ams/io/xlsx.py +80 -0
  50. ams/main.py +83 -4
  51. ams/models/__init__.py +24 -0
  52. ams/models/area.py +40 -0
  53. ams/models/bus.py +52 -0
  54. ams/models/cost.py +169 -0
  55. ams/models/distributed/__init__.py +3 -0
  56. ams/models/distributed/esd1.py +71 -0
  57. ams/models/distributed/ev.py +60 -0
  58. ams/models/distributed/pvd1.py +67 -0
  59. ams/models/group.py +231 -0
  60. ams/models/info.py +26 -0
  61. ams/models/line.py +238 -0
  62. ams/models/renewable/__init__.py +5 -0
  63. ams/models/renewable/regc.py +119 -0
  64. ams/models/reserve.py +94 -0
  65. ams/models/shunt.py +14 -0
  66. ams/models/static/__init__.py +2 -0
  67. ams/models/static/gen.py +165 -0
  68. ams/models/static/pq.py +61 -0
  69. ams/models/timeslot.py +69 -0
  70. ams/models/zone.py +49 -0
  71. ams/opt/__init__.py +12 -0
  72. ams/opt/constraint.py +175 -0
  73. ams/opt/exprcalc.py +127 -0
  74. ams/opt/expression.py +188 -0
  75. ams/opt/objective.py +174 -0
  76. ams/opt/omodel.py +432 -0
  77. ams/opt/optzbase.py +192 -0
  78. ams/opt/param.py +156 -0
  79. ams/opt/var.py +233 -0
  80. ams/pypower/__init__.py +8 -0
  81. ams/pypower/_compat.py +9 -0
  82. ams/pypower/core/__init__.py +8 -0
  83. ams/pypower/core/pips.py +894 -0
  84. ams/pypower/core/ppoption.py +244 -0
  85. ams/pypower/core/ppver.py +18 -0
  86. ams/pypower/core/solver.py +2451 -0
  87. ams/pypower/eps.py +6 -0
  88. ams/pypower/idx.py +174 -0
  89. ams/pypower/io.py +604 -0
  90. ams/pypower/make/__init__.py +11 -0
  91. ams/pypower/make/matrices.py +665 -0
  92. ams/pypower/make/pdv.py +506 -0
  93. ams/pypower/routines/__init__.py +7 -0
  94. ams/pypower/routines/cpf.py +513 -0
  95. ams/pypower/routines/cpf_callbacks.py +114 -0
  96. ams/pypower/routines/opf.py +1803 -0
  97. ams/pypower/routines/opffcns.py +1946 -0
  98. ams/pypower/routines/pflow.py +852 -0
  99. ams/pypower/toggle.py +1098 -0
  100. ams/pypower/utils.py +293 -0
  101. ams/report.py +212 -50
  102. ams/routines/__init__.py +23 -0
  103. ams/routines/acopf.py +117 -0
  104. ams/routines/cpf.py +65 -0
  105. ams/routines/dcopf.py +241 -0
  106. ams/routines/dcpf.py +209 -0
  107. ams/routines/dcpf0.py +196 -0
  108. ams/routines/dopf.py +150 -0
  109. ams/routines/ed.py +312 -0
  110. ams/routines/pflow.py +255 -0
  111. ams/routines/pflow0.py +113 -0
  112. ams/routines/pflow1.py +156 -0
  113. ams/routines/routine.py +1033 -0
  114. ams/routines/rted.py +519 -0
  115. ams/routines/type.py +160 -0
  116. ams/routines/uc.py +376 -0
  117. ams/shared.py +34 -9
  118. ams/system.py +61 -22
  119. ams/utils/__init__.py +3 -0
  120. ams/utils/misc.py +77 -0
  121. ams/utils/paths.py +257 -0
  122. docs/Makefile +21 -0
  123. docs/build/doctrees/nbsphinx/_examples_demo_demo_AGC_20_1.png +0 -0
  124. docs/build/doctrees/nbsphinx/_examples_demo_demo_AGC_37_1.png +0 -0
  125. docs/build/doctrees/nbsphinx/_examples_demo_demo_AGC_39_1.png +0 -0
  126. docs/build/html/_images/_examples_demo_demo_AGC_20_1.png +0 -0
  127. docs/build/html/_images/_examples_demo_demo_AGC_37_1.png +0 -0
  128. docs/build/html/_images/_examples_demo_demo_AGC_39_1.png +0 -0
  129. docs/build/html/_images/xlsx.png +0 -0
  130. docs/build/html/_static/file.png +0 -0
  131. docs/build/html/_static/minus.png +0 -0
  132. docs/build/html/_static/plus.png +0 -0
  133. docs/make.bat +35 -0
  134. docs/source/_generated/_generated/ams.core.model.Model.alter.rst +6 -0
  135. docs/source/_generated/_generated/ams.core.model.Model.class_name.rst +6 -0
  136. docs/source/_generated/_generated/ams.core.model.Model.doc.rst +6 -0
  137. docs/source/_generated/_generated/ams.core.model.Model.get.rst +6 -0
  138. docs/source/_generated/_generated/ams.core.model.Model.get_idx.rst +6 -0
  139. docs/source/_generated/_generated/ams.core.model.Model.idx2uid.rst +6 -0
  140. docs/source/_generated/_generated/ams.core.model.Model.list2array.rst +6 -0
  141. docs/source/_generated/_generated/ams.core.model.Model.set.rst +6 -0
  142. docs/source/_generated/_generated/ams.core.model.Model.set_backref.rst +6 -0
  143. docs/source/_generated/_generated/ams.core.param.RParam.class_name.rst +6 -0
  144. docs/source/_generated/_generated/ams.core.param.RParam.dtype.rst +6 -0
  145. docs/source/_generated/_generated/ams.core.param.RParam.evaluate.rst +6 -0
  146. docs/source/_generated/_generated/ams.core.param.RParam.get_idx.rst +6 -0
  147. docs/source/_generated/_generated/ams.core.param.RParam.n.rst +6 -0
  148. docs/source/_generated/_generated/ams.core.param.RParam.parse.rst +6 -0
  149. docs/source/_generated/_generated/ams.core.param.RParam.shape.rst +6 -0
  150. docs/source/_generated/_generated/ams.core.param.RParam.size.rst +6 -0
  151. docs/source/_generated/_generated/ams.core.param.RParam.update.rst +6 -0
  152. docs/source/_generated/_generated/ams.core.param.RParam.v.rst +6 -0
  153. docs/source/_generated/_generated/ams.core.service.LoadScale.assign_memory.rst +6 -0
  154. docs/source/_generated/_generated/ams.core.service.LoadScale.class_name.rst +6 -0
  155. docs/source/_generated/_generated/ams.core.service.LoadScale.evaluate.rst +6 -0
  156. docs/source/_generated/_generated/ams.core.service.LoadScale.get_names.rst +6 -0
  157. docs/source/_generated/_generated/ams.core.service.LoadScale.n.rst +6 -0
  158. docs/source/_generated/_generated/ams.core.service.LoadScale.parse.rst +6 -0
  159. docs/source/_generated/_generated/ams.core.service.LoadScale.shape.rst +6 -0
  160. docs/source/_generated/_generated/ams.core.service.LoadScale.size.rst +6 -0
  161. docs/source/_generated/_generated/ams.core.service.LoadScale.update.rst +6 -0
  162. docs/source/_generated/_generated/ams.core.service.LoadScale.v.rst +6 -0
  163. docs/source/_generated/_generated/ams.core.service.MinDur.assign_memory.rst +6 -0
  164. docs/source/_generated/_generated/ams.core.service.MinDur.class_name.rst +6 -0
  165. docs/source/_generated/_generated/ams.core.service.MinDur.evaluate.rst +6 -0
  166. docs/source/_generated/_generated/ams.core.service.MinDur.get_names.rst +6 -0
  167. docs/source/_generated/_generated/ams.core.service.MinDur.n.rst +6 -0
  168. docs/source/_generated/_generated/ams.core.service.MinDur.parse.rst +6 -0
  169. docs/source/_generated/_generated/ams.core.service.MinDur.shape.rst +6 -0
  170. docs/source/_generated/_generated/ams.core.service.MinDur.size.rst +6 -0
  171. docs/source/_generated/_generated/ams.core.service.MinDur.update.rst +6 -0
  172. docs/source/_generated/_generated/ams.core.service.MinDur.v.rst +6 -0
  173. docs/source/_generated/_generated/ams.core.service.MinDur.v0.rst +6 -0
  174. docs/source/_generated/_generated/ams.core.service.MinDur.v1.rst +6 -0
  175. docs/source/_generated/_generated/ams.core.service.NumExpandDim.assign_memory.rst +6 -0
  176. docs/source/_generated/_generated/ams.core.service.NumExpandDim.class_name.rst +6 -0
  177. docs/source/_generated/_generated/ams.core.service.NumExpandDim.evaluate.rst +6 -0
  178. docs/source/_generated/_generated/ams.core.service.NumExpandDim.get_names.rst +6 -0
  179. docs/source/_generated/_generated/ams.core.service.NumExpandDim.n.rst +6 -0
  180. docs/source/_generated/_generated/ams.core.service.NumExpandDim.parse.rst +6 -0
  181. docs/source/_generated/_generated/ams.core.service.NumExpandDim.shape.rst +6 -0
  182. docs/source/_generated/_generated/ams.core.service.NumExpandDim.size.rst +6 -0
  183. docs/source/_generated/_generated/ams.core.service.NumExpandDim.update.rst +6 -0
  184. docs/source/_generated/_generated/ams.core.service.NumExpandDim.v.rst +6 -0
  185. docs/source/_generated/_generated/ams.core.service.NumExpandDim.v0.rst +6 -0
  186. docs/source/_generated/_generated/ams.core.service.NumExpandDim.v1.rst +6 -0
  187. docs/source/_generated/_generated/ams.core.service.NumHstack.assign_memory.rst +6 -0
  188. docs/source/_generated/_generated/ams.core.service.NumHstack.class_name.rst +6 -0
  189. docs/source/_generated/_generated/ams.core.service.NumHstack.evaluate.rst +6 -0
  190. docs/source/_generated/_generated/ams.core.service.NumHstack.get_names.rst +6 -0
  191. docs/source/_generated/_generated/ams.core.service.NumHstack.n.rst +6 -0
  192. docs/source/_generated/_generated/ams.core.service.NumHstack.parse.rst +6 -0
  193. docs/source/_generated/_generated/ams.core.service.NumHstack.shape.rst +6 -0
  194. docs/source/_generated/_generated/ams.core.service.NumHstack.size.rst +6 -0
  195. docs/source/_generated/_generated/ams.core.service.NumHstack.update.rst +6 -0
  196. docs/source/_generated/_generated/ams.core.service.NumHstack.v.rst +6 -0
  197. docs/source/_generated/_generated/ams.core.service.NumHstack.v0.rst +6 -0
  198. docs/source/_generated/_generated/ams.core.service.NumHstack.v1.rst +6 -0
  199. docs/source/_generated/_generated/ams.core.service.NumOp.assign_memory.rst +6 -0
  200. docs/source/_generated/_generated/ams.core.service.NumOp.class_name.rst +6 -0
  201. docs/source/_generated/_generated/ams.core.service.NumOp.evaluate.rst +6 -0
  202. docs/source/_generated/_generated/ams.core.service.NumOp.get_names.rst +6 -0
  203. docs/source/_generated/_generated/ams.core.service.NumOp.n.rst +6 -0
  204. docs/source/_generated/_generated/ams.core.service.NumOp.parse.rst +6 -0
  205. docs/source/_generated/_generated/ams.core.service.NumOp.shape.rst +6 -0
  206. docs/source/_generated/_generated/ams.core.service.NumOp.size.rst +6 -0
  207. docs/source/_generated/_generated/ams.core.service.NumOp.update.rst +6 -0
  208. docs/source/_generated/_generated/ams.core.service.NumOp.v.rst +6 -0
  209. docs/source/_generated/_generated/ams.core.service.NumOp.v0.rst +6 -0
  210. docs/source/_generated/_generated/ams.core.service.NumOp.v1.rst +6 -0
  211. docs/source/_generated/_generated/ams.core.service.NumOpDual.assign_memory.rst +6 -0
  212. docs/source/_generated/_generated/ams.core.service.NumOpDual.class_name.rst +6 -0
  213. docs/source/_generated/_generated/ams.core.service.NumOpDual.evaluate.rst +6 -0
  214. docs/source/_generated/_generated/ams.core.service.NumOpDual.get_names.rst +6 -0
  215. docs/source/_generated/_generated/ams.core.service.NumOpDual.n.rst +6 -0
  216. docs/source/_generated/_generated/ams.core.service.NumOpDual.parse.rst +6 -0
  217. docs/source/_generated/_generated/ams.core.service.NumOpDual.shape.rst +6 -0
  218. docs/source/_generated/_generated/ams.core.service.NumOpDual.size.rst +6 -0
  219. docs/source/_generated/_generated/ams.core.service.NumOpDual.update.rst +6 -0
  220. docs/source/_generated/_generated/ams.core.service.NumOpDual.v.rst +6 -0
  221. docs/source/_generated/_generated/ams.core.service.NumOpDual.v0.rst +6 -0
  222. docs/source/_generated/_generated/ams.core.service.NumOpDual.v1.rst +6 -0
  223. docs/source/_generated/_generated/ams.core.service.RBaseService.assign_memory.rst +6 -0
  224. docs/source/_generated/_generated/ams.core.service.RBaseService.class_name.rst +6 -0
  225. docs/source/_generated/_generated/ams.core.service.RBaseService.evaluate.rst +6 -0
  226. docs/source/_generated/_generated/ams.core.service.RBaseService.get_names.rst +6 -0
  227. docs/source/_generated/_generated/ams.core.service.RBaseService.n.rst +6 -0
  228. docs/source/_generated/_generated/ams.core.service.RBaseService.parse.rst +6 -0
  229. docs/source/_generated/_generated/ams.core.service.RBaseService.shape.rst +6 -0
  230. docs/source/_generated/_generated/ams.core.service.RBaseService.size.rst +6 -0
  231. docs/source/_generated/_generated/ams.core.service.RBaseService.update.rst +6 -0
  232. docs/source/_generated/_generated/ams.core.service.RBaseService.v.rst +6 -0
  233. docs/source/_generated/_generated/ams.core.service.ROperationService.assign_memory.rst +6 -0
  234. docs/source/_generated/_generated/ams.core.service.ROperationService.class_name.rst +6 -0
  235. docs/source/_generated/_generated/ams.core.service.ROperationService.evaluate.rst +6 -0
  236. docs/source/_generated/_generated/ams.core.service.ROperationService.get_names.rst +6 -0
  237. docs/source/_generated/_generated/ams.core.service.ROperationService.n.rst +6 -0
  238. docs/source/_generated/_generated/ams.core.service.ROperationService.parse.rst +6 -0
  239. docs/source/_generated/_generated/ams.core.service.ROperationService.shape.rst +6 -0
  240. docs/source/_generated/_generated/ams.core.service.ROperationService.size.rst +6 -0
  241. docs/source/_generated/_generated/ams.core.service.ROperationService.update.rst +6 -0
  242. docs/source/_generated/_generated/ams.core.service.ROperationService.v.rst +6 -0
  243. docs/source/_generated/_generated/ams.core.service.RampSub.assign_memory.rst +6 -0
  244. docs/source/_generated/_generated/ams.core.service.RampSub.class_name.rst +6 -0
  245. docs/source/_generated/_generated/ams.core.service.RampSub.evaluate.rst +6 -0
  246. docs/source/_generated/_generated/ams.core.service.RampSub.get_names.rst +6 -0
  247. docs/source/_generated/_generated/ams.core.service.RampSub.n.rst +6 -0
  248. docs/source/_generated/_generated/ams.core.service.RampSub.parse.rst +6 -0
  249. docs/source/_generated/_generated/ams.core.service.RampSub.shape.rst +6 -0
  250. docs/source/_generated/_generated/ams.core.service.RampSub.size.rst +6 -0
  251. docs/source/_generated/_generated/ams.core.service.RampSub.update.rst +6 -0
  252. docs/source/_generated/_generated/ams.core.service.RampSub.v.rst +6 -0
  253. docs/source/_generated/_generated/ams.core.service.RampSub.v0.rst +6 -0
  254. docs/source/_generated/_generated/ams.core.service.RampSub.v1.rst +6 -0
  255. docs/source/_generated/_generated/ams.core.service.ValueService.assign_memory.rst +6 -0
  256. docs/source/_generated/_generated/ams.core.service.ValueService.class_name.rst +6 -0
  257. docs/source/_generated/_generated/ams.core.service.ValueService.evaluate.rst +6 -0
  258. docs/source/_generated/_generated/ams.core.service.ValueService.get_names.rst +6 -0
  259. docs/source/_generated/_generated/ams.core.service.ValueService.n.rst +6 -0
  260. docs/source/_generated/_generated/ams.core.service.ValueService.parse.rst +6 -0
  261. docs/source/_generated/_generated/ams.core.service.ValueService.shape.rst +6 -0
  262. docs/source/_generated/_generated/ams.core.service.ValueService.size.rst +6 -0
  263. docs/source/_generated/_generated/ams.core.service.ValueService.update.rst +6 -0
  264. docs/source/_generated/_generated/ams.core.service.ValueService.v.rst +6 -0
  265. docs/source/_generated/_generated/ams.core.service.VarReduction.assign_memory.rst +6 -0
  266. docs/source/_generated/_generated/ams.core.service.VarReduction.class_name.rst +6 -0
  267. docs/source/_generated/_generated/ams.core.service.VarReduction.evaluate.rst +6 -0
  268. docs/source/_generated/_generated/ams.core.service.VarReduction.get_names.rst +6 -0
  269. docs/source/_generated/_generated/ams.core.service.VarReduction.n.rst +6 -0
  270. docs/source/_generated/_generated/ams.core.service.VarReduction.parse.rst +6 -0
  271. docs/source/_generated/_generated/ams.core.service.VarReduction.shape.rst +6 -0
  272. docs/source/_generated/_generated/ams.core.service.VarReduction.size.rst +6 -0
  273. docs/source/_generated/_generated/ams.core.service.VarReduction.update.rst +6 -0
  274. docs/source/_generated/_generated/ams.core.service.VarReduction.v.rst +6 -0
  275. docs/source/_generated/_generated/ams.core.service.VarReduction.v0.rst +6 -0
  276. docs/source/_generated/_generated/ams.core.service.VarReduction.v1.rst +6 -0
  277. docs/source/_generated/_generated/ams.core.service.VarSelect.assign_memory.rst +6 -0
  278. docs/source/_generated/_generated/ams.core.service.VarSelect.class_name.rst +6 -0
  279. docs/source/_generated/_generated/ams.core.service.VarSelect.evaluate.rst +6 -0
  280. docs/source/_generated/_generated/ams.core.service.VarSelect.get_names.rst +6 -0
  281. docs/source/_generated/_generated/ams.core.service.VarSelect.n.rst +6 -0
  282. docs/source/_generated/_generated/ams.core.service.VarSelect.parse.rst +6 -0
  283. docs/source/_generated/_generated/ams.core.service.VarSelect.shape.rst +6 -0
  284. docs/source/_generated/_generated/ams.core.service.VarSelect.size.rst +6 -0
  285. docs/source/_generated/_generated/ams.core.service.VarSelect.update.rst +6 -0
  286. docs/source/_generated/_generated/ams.core.service.VarSelect.v.rst +6 -0
  287. docs/source/_generated/_generated/ams.core.service.VarSelect.v0.rst +6 -0
  288. docs/source/_generated/_generated/ams.core.service.VarSelect.v1.rst +6 -0
  289. docs/source/_generated/_generated/ams.core.service.ZonalSum.assign_memory.rst +6 -0
  290. docs/source/_generated/_generated/ams.core.service.ZonalSum.class_name.rst +6 -0
  291. docs/source/_generated/_generated/ams.core.service.ZonalSum.evaluate.rst +6 -0
  292. docs/source/_generated/_generated/ams.core.service.ZonalSum.get_names.rst +6 -0
  293. docs/source/_generated/_generated/ams.core.service.ZonalSum.n.rst +6 -0
  294. docs/source/_generated/_generated/ams.core.service.ZonalSum.parse.rst +6 -0
  295. docs/source/_generated/_generated/ams.core.service.ZonalSum.shape.rst +6 -0
  296. docs/source/_generated/_generated/ams.core.service.ZonalSum.size.rst +6 -0
  297. docs/source/_generated/_generated/ams.core.service.ZonalSum.update.rst +6 -0
  298. docs/source/_generated/_generated/ams.core.service.ZonalSum.v.rst +6 -0
  299. docs/source/_generated/_generated/ams.core.service.ZonalSum.v0.rst +6 -0
  300. docs/source/_generated/_generated/ams.core.service.ZonalSum.v1.rst +6 -0
  301. docs/source/_generated/_generated/ams.interface.Dynamic.is_tds.rst +6 -0
  302. docs/source/_generated/_generated/ams.interface.Dynamic.link_andes.rst +6 -0
  303. docs/source/_generated/_generated/ams.interface.Dynamic.receive.rst +6 -0
  304. docs/source/_generated/_generated/ams.interface.Dynamic.send.rst +6 -0
  305. docs/source/_generated/_generated/ams.opt.constraint.Constraint.class_name.rst +6 -0
  306. docs/source/_generated/_generated/ams.opt.constraint.Constraint.e.rst +6 -0
  307. docs/source/_generated/_generated/ams.opt.constraint.Constraint.evaluate.rst +6 -0
  308. docs/source/_generated/_generated/ams.opt.constraint.Constraint.n.rst +6 -0
  309. docs/source/_generated/_generated/ams.opt.constraint.Constraint.parse.rst +6 -0
  310. docs/source/_generated/_generated/ams.opt.constraint.Constraint.shape.rst +6 -0
  311. docs/source/_generated/_generated/ams.opt.constraint.Constraint.size.rst +6 -0
  312. docs/source/_generated/_generated/ams.opt.constraint.Constraint.v.rst +6 -0
  313. docs/source/_generated/_generated/ams.opt.exprcalc.ExpressionCalc.class_name.rst +6 -0
  314. docs/source/_generated/_generated/ams.opt.exprcalc.ExpressionCalc.e.rst +6 -0
  315. docs/source/_generated/_generated/ams.opt.exprcalc.ExpressionCalc.evaluate.rst +6 -0
  316. docs/source/_generated/_generated/ams.opt.exprcalc.ExpressionCalc.get_idx.rst +6 -0
  317. docs/source/_generated/_generated/ams.opt.exprcalc.ExpressionCalc.n.rst +6 -0
  318. docs/source/_generated/_generated/ams.opt.exprcalc.ExpressionCalc.parse.rst +6 -0
  319. docs/source/_generated/_generated/ams.opt.exprcalc.ExpressionCalc.shape.rst +6 -0
  320. docs/source/_generated/_generated/ams.opt.exprcalc.ExpressionCalc.size.rst +6 -0
  321. docs/source/_generated/_generated/ams.opt.exprcalc.ExpressionCalc.v.rst +6 -0
  322. docs/source/_generated/_generated/ams.opt.expression.Expression.class_name.rst +6 -0
  323. docs/source/_generated/_generated/ams.opt.expression.Expression.e.rst +6 -0
  324. docs/source/_generated/_generated/ams.opt.expression.Expression.evaluate.rst +6 -0
  325. docs/source/_generated/_generated/ams.opt.expression.Expression.get_idx.rst +6 -0
  326. docs/source/_generated/_generated/ams.opt.expression.Expression.n.rst +6 -0
  327. docs/source/_generated/_generated/ams.opt.expression.Expression.parse.rst +6 -0
  328. docs/source/_generated/_generated/ams.opt.expression.Expression.shape.rst +6 -0
  329. docs/source/_generated/_generated/ams.opt.expression.Expression.size.rst +6 -0
  330. docs/source/_generated/_generated/ams.opt.expression.Expression.v.rst +6 -0
  331. docs/source/_generated/_generated/ams.opt.objective.Objective.class_name.rst +6 -0
  332. docs/source/_generated/_generated/ams.opt.objective.Objective.e.rst +6 -0
  333. docs/source/_generated/_generated/ams.opt.objective.Objective.evaluate.rst +6 -0
  334. docs/source/_generated/_generated/ams.opt.objective.Objective.n.rst +6 -0
  335. docs/source/_generated/_generated/ams.opt.objective.Objective.parse.rst +6 -0
  336. docs/source/_generated/_generated/ams.opt.objective.Objective.shape.rst +6 -0
  337. docs/source/_generated/_generated/ams.opt.objective.Objective.size.rst +6 -0
  338. docs/source/_generated/_generated/ams.opt.objective.Objective.v.rst +6 -0
  339. docs/source/_generated/_generated/ams.opt.omodel.OModel.class_name.rst +6 -0
  340. docs/source/_generated/_generated/ams.opt.omodel.OModel.evaluate.rst +6 -0
  341. docs/source/_generated/_generated/ams.opt.omodel.OModel.finalize.rst +6 -0
  342. docs/source/_generated/_generated/ams.opt.omodel.OModel.init.rst +6 -0
  343. docs/source/_generated/_generated/ams.opt.omodel.OModel.initialized.rst +6 -0
  344. docs/source/_generated/_generated/ams.opt.omodel.OModel.parse.rst +6 -0
  345. docs/source/_generated/_generated/ams.opt.omodel.OModel.update.rst +6 -0
  346. docs/source/_generated/_generated/ams.opt.omodel.OModelBase.class_name.rst +6 -0
  347. docs/source/_generated/_generated/ams.opt.omodel.OModelBase.evaluate.rst +6 -0
  348. docs/source/_generated/_generated/ams.opt.omodel.OModelBase.finalize.rst +6 -0
  349. docs/source/_generated/_generated/ams.opt.omodel.OModelBase.init.rst +6 -0
  350. docs/source/_generated/_generated/ams.opt.omodel.OModelBase.initialized.rst +6 -0
  351. docs/source/_generated/_generated/ams.opt.omodel.OModelBase.parse.rst +6 -0
  352. docs/source/_generated/_generated/ams.opt.omodel.OModelBase.update.rst +6 -0
  353. docs/source/_generated/_generated/ams.opt.optbase.OptzBase.class_name.rst +6 -0
  354. docs/source/_generated/_generated/ams.opt.optbase.OptzBase.evaluate.rst +6 -0
  355. docs/source/_generated/_generated/ams.opt.optbase.OptzBase.n.rst +6 -0
  356. docs/source/_generated/_generated/ams.opt.optbase.OptzBase.parse.rst +6 -0
  357. docs/source/_generated/_generated/ams.opt.optbase.OptzBase.shape.rst +6 -0
  358. docs/source/_generated/_generated/ams.opt.optbase.OptzBase.size.rst +6 -0
  359. docs/source/_generated/_generated/ams.opt.param.Param.class_name.rst +6 -0
  360. docs/source/_generated/_generated/ams.opt.param.Param.evaluate.rst +6 -0
  361. docs/source/_generated/_generated/ams.opt.param.Param.n.rst +6 -0
  362. docs/source/_generated/_generated/ams.opt.param.Param.parse.rst +6 -0
  363. docs/source/_generated/_generated/ams.opt.param.Param.shape.rst +6 -0
  364. docs/source/_generated/_generated/ams.opt.param.Param.size.rst +6 -0
  365. docs/source/_generated/_generated/ams.opt.param.Param.update.rst +6 -0
  366. docs/source/_generated/_generated/ams.opt.var.Var.class_name.rst +6 -0
  367. docs/source/_generated/_generated/ams.opt.var.Var.evaluate.rst +6 -0
  368. docs/source/_generated/_generated/ams.opt.var.Var.get_idx.rst +6 -0
  369. docs/source/_generated/_generated/ams.opt.var.Var.n.rst +6 -0
  370. docs/source/_generated/_generated/ams.opt.var.Var.parse.rst +6 -0
  371. docs/source/_generated/_generated/ams.opt.var.Var.shape.rst +6 -0
  372. docs/source/_generated/_generated/ams.opt.var.Var.size.rst +6 -0
  373. docs/source/_generated/_generated/ams.opt.var.Var.v.rst +6 -0
  374. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.addConstrs.rst +6 -0
  375. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.addRParam.rst +6 -0
  376. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.addService.rst +6 -0
  377. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.addVars.rst +6 -0
  378. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.class_name.rst +6 -0
  379. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.dc2ac.rst +6 -0
  380. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.disable.rst +6 -0
  381. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.doc.rst +6 -0
  382. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.enable.rst +6 -0
  383. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.export_csv.rst +6 -0
  384. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.get.rst +6 -0
  385. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.init.rst +6 -0
  386. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.run.rst +6 -0
  387. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.set.rst +6 -0
  388. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.solve.rst +6 -0
  389. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.summary.rst +6 -0
  390. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.unpack.rst +6 -0
  391. docs/source/_generated/_generated/ams.routines.dcopf.DCOPF.update.rst +6 -0
  392. docs/source/_generated/_generated/ams.routines.pflow.PFlow.addConstrs.rst +6 -0
  393. docs/source/_generated/_generated/ams.routines.pflow.PFlow.addRParam.rst +6 -0
  394. docs/source/_generated/_generated/ams.routines.pflow.PFlow.addService.rst +6 -0
  395. docs/source/_generated/_generated/ams.routines.pflow.PFlow.addVars.rst +6 -0
  396. docs/source/_generated/_generated/ams.routines.pflow.PFlow.class_name.rst +6 -0
  397. docs/source/_generated/_generated/ams.routines.pflow.PFlow.dc2ac.rst +6 -0
  398. docs/source/_generated/_generated/ams.routines.pflow.PFlow.disable.rst +6 -0
  399. docs/source/_generated/_generated/ams.routines.pflow.PFlow.doc.rst +6 -0
  400. docs/source/_generated/_generated/ams.routines.pflow.PFlow.enable.rst +6 -0
  401. docs/source/_generated/_generated/ams.routines.pflow.PFlow.export_csv.rst +6 -0
  402. docs/source/_generated/_generated/ams.routines.pflow.PFlow.get.rst +6 -0
  403. docs/source/_generated/_generated/ams.routines.pflow.PFlow.init.rst +6 -0
  404. docs/source/_generated/_generated/ams.routines.pflow.PFlow.run.rst +6 -0
  405. docs/source/_generated/_generated/ams.routines.pflow.PFlow.set.rst +6 -0
  406. docs/source/_generated/_generated/ams.routines.pflow.PFlow.solve.rst +6 -0
  407. docs/source/_generated/_generated/ams.routines.pflow.PFlow.summary.rst +6 -0
  408. docs/source/_generated/_generated/ams.routines.pflow.PFlow.unpack.rst +6 -0
  409. docs/source/_generated/_generated/ams.routines.pflow.PFlow.update.rst +6 -0
  410. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.addConstrs.rst +6 -0
  411. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.addRParam.rst +6 -0
  412. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.addService.rst +6 -0
  413. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.addVars.rst +6 -0
  414. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.class_name.rst +6 -0
  415. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.dc2ac.rst +6 -0
  416. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.disable.rst +6 -0
  417. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.doc.rst +6 -0
  418. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.enable.rst +6 -0
  419. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.export_csv.rst +6 -0
  420. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.get.rst +6 -0
  421. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.init.rst +6 -0
  422. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.run.rst +6 -0
  423. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.set.rst +6 -0
  424. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.solve.rst +6 -0
  425. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.summary.rst +6 -0
  426. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.unpack.rst +6 -0
  427. docs/source/_generated/_generated/ams.routines.routine.RoutineBase.update.rst +6 -0
  428. docs/source/_generated/_generated/ams.system.System.add.rst +6 -0
  429. docs/source/_generated/_generated/ams.system.System.as_dict.rst +6 -0
  430. docs/source/_generated/_generated/ams.system.System.calc_pu_coeff.rst +6 -0
  431. docs/source/_generated/_generated/ams.system.System.call_models.rst +6 -0
  432. docs/source/_generated/_generated/ams.system.System.collect_config.rst +6 -0
  433. docs/source/_generated/_generated/ams.system.System.collect_ref.rst +6 -0
  434. docs/source/_generated/_generated/ams.system.System.connectivity.rst +6 -0
  435. docs/source/_generated/_generated/ams.system.System.e_clear.rst +6 -0
  436. docs/source/_generated/_generated/ams.system.System.f_update.rst +6 -0
  437. docs/source/_generated/_generated/ams.system.System.fg_to_dae.rst +6 -0
  438. docs/source/_generated/_generated/ams.system.System.find_devices.rst +6 -0
  439. docs/source/_generated/_generated/ams.system.System.find_models.rst +6 -0
  440. docs/source/_generated/_generated/ams.system.System.from_ipysheet.rst +6 -0
  441. docs/source/_generated/_generated/ams.system.System.g_islands.rst +6 -0
  442. docs/source/_generated/_generated/ams.system.System.g_update.rst +6 -0
  443. docs/source/_generated/_generated/ams.system.System.get_z.rst +6 -0
  444. docs/source/_generated/_generated/ams.system.System.import_groups.rst +6 -0
  445. docs/source/_generated/_generated/ams.system.System.import_models.rst +6 -0
  446. docs/source/_generated/_generated/ams.system.System.import_routines.rst +6 -0
  447. docs/source/_generated/_generated/ams.system.System.import_types.rst +6 -0
  448. docs/source/_generated/_generated/ams.system.System.init.rst +6 -0
  449. docs/source/_generated/_generated/ams.system.System.j_islands.rst +6 -0
  450. docs/source/_generated/_generated/ams.system.System.j_update.rst +6 -0
  451. docs/source/_generated/_generated/ams.system.System.l_update_eq.rst +6 -0
  452. docs/source/_generated/_generated/ams.system.System.l_update_var.rst +6 -0
  453. docs/source/_generated/_generated/ams.system.System.link_ext_param.rst +6 -0
  454. docs/source/_generated/_generated/ams.system.System.precompile.rst +6 -0
  455. docs/source/_generated/_generated/ams.system.System.prepare.rst +6 -0
  456. docs/source/_generated/_generated/ams.system.System.reload.rst +6 -0
  457. docs/source/_generated/_generated/ams.system.System.remove_pycapsule.rst +6 -0
  458. docs/source/_generated/_generated/ams.system.System.report.rst +6 -0
  459. docs/source/_generated/_generated/ams.system.System.reset.rst +6 -0
  460. docs/source/_generated/_generated/ams.system.System.s_update_post.rst +6 -0
  461. docs/source/_generated/_generated/ams.system.System.s_update_var.rst +6 -0
  462. docs/source/_generated/_generated/ams.system.System.save_config.rst +6 -0
  463. docs/source/_generated/_generated/ams.system.System.set_address.rst +6 -0
  464. docs/source/_generated/_generated/ams.system.System.set_config.rst +6 -0
  465. docs/source/_generated/_generated/ams.system.System.set_dae_names.rst +6 -0
  466. docs/source/_generated/_generated/ams.system.System.set_output_subidx.rst +6 -0
  467. docs/source/_generated/_generated/ams.system.System.set_var_arrays.rst +6 -0
  468. docs/source/_generated/_generated/ams.system.System.setup.rst +6 -0
  469. docs/source/_generated/_generated/ams.system.System.store_adder_setter.rst +6 -0
  470. docs/source/_generated/_generated/ams.system.System.store_existing.rst +6 -0
  471. docs/source/_generated/_generated/ams.system.System.store_no_check_init.rst +6 -0
  472. docs/source/_generated/_generated/ams.system.System.store_sparse_pattern.rst +6 -0
  473. docs/source/_generated/_generated/ams.system.System.store_switch_times.rst +6 -0
  474. docs/source/_generated/_generated/ams.system.System.summary.rst +6 -0
  475. docs/source/_generated/_generated/ams.system.System.supported_models.rst +6 -0
  476. docs/source/_generated/_generated/ams.system.System.supported_routines.rst +6 -0
  477. docs/source/_generated/_generated/ams.system.System.switch_action.rst +6 -0
  478. docs/source/_generated/_generated/ams.system.System.to_andes.rst +6 -0
  479. docs/source/_generated/_generated/ams.system.System.to_ipysheet.rst +6 -0
  480. docs/source/_generated/_generated/ams.system.System.undill.rst +6 -0
  481. docs/source/_generated/_generated/ams.system.System.vars_to_dae.rst +6 -0
  482. docs/source/_generated/_generated/ams.system.System.vars_to_models.rst +6 -0
  483. docs/source/_generated/_generated/ams.utils.paths.DisplayablePath.display_filename_prefix_last.rst +6 -0
  484. docs/source/_generated/_generated/ams.utils.paths.DisplayablePath.display_filename_prefix_middle.rst +6 -0
  485. docs/source/_generated/_generated/ams.utils.paths.DisplayablePath.display_parent_prefix_last.rst +6 -0
  486. docs/source/_generated/_generated/ams.utils.paths.DisplayablePath.display_parent_prefix_middle.rst +6 -0
  487. docs/source/_generated/_generated/ams.utils.paths.DisplayablePath.displayable.rst +6 -0
  488. docs/source/_generated/_generated/ams.utils.paths.DisplayablePath.displayname.rst +6 -0
  489. docs/source/_generated/_generated/ams.utils.paths.DisplayablePath.make_tree.rst +6 -0
  490. docs/source/_generated/ams.cli.create_parser.rst +6 -0
  491. docs/source/_generated/ams.cli.main.rst +6 -0
  492. docs/source/_generated/ams.cli.preamble.rst +6 -0
  493. docs/source/_generated/ams.cli.rst +32 -0
  494. docs/source/_generated/ams.core.model.Model.rst +56 -0
  495. docs/source/_generated/ams.core.model.rst +30 -0
  496. docs/source/_generated/ams.core.param.RParam.rst +49 -0
  497. docs/source/_generated/ams.core.param.rst +30 -0
  498. docs/source/_generated/ams.core.service.LoadScale.rst +51 -0
  499. docs/source/_generated/ams.core.service.MinDur.rst +53 -0
  500. docs/source/_generated/ams.core.service.NumExpandDim.rst +53 -0
  501. docs/source/_generated/ams.core.service.NumHstack.rst +53 -0
  502. docs/source/_generated/ams.core.service.NumOp.rst +53 -0
  503. docs/source/_generated/ams.core.service.NumOpDual.rst +53 -0
  504. docs/source/_generated/ams.core.service.RBaseService.rst +51 -0
  505. docs/source/_generated/ams.core.service.ROperationService.rst +51 -0
  506. docs/source/_generated/ams.core.service.RampSub.rst +53 -0
  507. docs/source/_generated/ams.core.service.ValueService.rst +51 -0
  508. docs/source/_generated/ams.core.service.VarReduction.rst +53 -0
  509. docs/source/_generated/ams.core.service.VarSelect.rst +53 -0
  510. docs/source/_generated/ams.core.service.ZonalSum.rst +53 -0
  511. docs/source/_generated/ams.core.service.rst +42 -0
  512. docs/source/_generated/ams.interface.Dynamic.rst +41 -0
  513. docs/source/_generated/ams.interface.build_group_table.rst +6 -0
  514. docs/source/_generated/ams.interface.make_link_table.rst +6 -0
  515. docs/source/_generated/ams.interface.parse_addfile.rst +6 -0
  516. docs/source/_generated/ams.interface.replace_dev.rst +6 -0
  517. docs/source/_generated/ams.interface.rst +43 -0
  518. docs/source/_generated/ams.interface.sync_adsys.rst +6 -0
  519. docs/source/_generated/ams.interface.to_andes.rst +6 -0
  520. docs/source/_generated/ams.interface.verify_pf.rst +6 -0
  521. docs/source/_generated/ams.io.guess.rst +6 -0
  522. docs/source/_generated/ams.io.json.rst +30 -0
  523. docs/source/_generated/ams.io.json.write.rst +6 -0
  524. docs/source/_generated/ams.io.matpower.mpc2system.rst +6 -0
  525. docs/source/_generated/ams.io.matpower.read.rst +6 -0
  526. docs/source/_generated/ams.io.matpower.rst +33 -0
  527. docs/source/_generated/ams.io.matpower.system2mpc.rst +6 -0
  528. docs/source/_generated/ams.io.matpower.testlines.rst +6 -0
  529. docs/source/_generated/ams.io.parse.rst +6 -0
  530. docs/source/_generated/ams.io.psse.rst +23 -0
  531. docs/source/_generated/ams.io.pypower.ppc2system.rst +6 -0
  532. docs/source/_generated/ams.io.pypower.py2ppc.rst +6 -0
  533. docs/source/_generated/ams.io.pypower.read.rst +6 -0
  534. docs/source/_generated/ams.io.pypower.rst +34 -0
  535. docs/source/_generated/ams.io.pypower.system2ppc.rst +6 -0
  536. docs/source/_generated/ams.io.pypower.testlines.rst +6 -0
  537. docs/source/_generated/ams.io.rst +45 -0
  538. docs/source/_generated/ams.io.xlsx.rst +30 -0
  539. docs/source/_generated/ams.io.xlsx.write.rst +6 -0
  540. docs/source/_generated/ams.main.config_logger.rst +6 -0
  541. docs/source/_generated/ams.main.demo.rst +6 -0
  542. docs/source/_generated/ams.main.doc.rst +6 -0
  543. docs/source/_generated/ams.main.edit_conf.rst +6 -0
  544. docs/source/_generated/ams.main.find_log_path.rst +6 -0
  545. docs/source/_generated/ams.main.load.rst +6 -0
  546. docs/source/_generated/ams.main.misc.rst +6 -0
  547. docs/source/_generated/ams.main.print_license.rst +6 -0
  548. docs/source/_generated/ams.main.remove_output.rst +6 -0
  549. docs/source/_generated/ams.main.rst +44 -0
  550. docs/source/_generated/ams.main.run.rst +6 -0
  551. docs/source/_generated/ams.main.run_case.rst +6 -0
  552. docs/source/_generated/ams.main.save_conf.rst +6 -0
  553. docs/source/_generated/ams.main.selftest.rst +6 -0
  554. docs/source/_generated/ams.main.set_logger_level.rst +6 -0
  555. docs/source/_generated/ams.main.versioninfo.rst +6 -0
  556. docs/source/_generated/ams.opt.constraint.Constraint.rst +43 -0
  557. docs/source/_generated/ams.opt.constraint.rst +30 -0
  558. docs/source/_generated/ams.opt.exprcalc.ExpressionCalc.rst +46 -0
  559. docs/source/_generated/ams.opt.exprcalc.rst +30 -0
  560. docs/source/_generated/ams.opt.expression.Expression.rst +46 -0
  561. docs/source/_generated/ams.opt.expression.rst +30 -0
  562. docs/source/_generated/ams.opt.objective.Objective.rst +43 -0
  563. docs/source/_generated/ams.opt.objective.rst +30 -0
  564. docs/source/_generated/ams.opt.omodel.OModel.rst +48 -0
  565. docs/source/_generated/ams.opt.omodel.OModelBase.rst +48 -0
  566. docs/source/_generated/ams.opt.omodel.rst +31 -0
  567. docs/source/_generated/ams.opt.optbase.OptzBase.rst +41 -0
  568. docs/source/_generated/ams.opt.optbase.ensure_mats_and_parsed.rst +6 -0
  569. docs/source/_generated/ams.opt.optbase.ensure_symbols.rst +6 -0
  570. docs/source/_generated/ams.opt.optbase.rst +38 -0
  571. docs/source/_generated/ams.opt.param.Param.rst +44 -0
  572. docs/source/_generated/ams.opt.param.rst +30 -0
  573. docs/source/_generated/ams.opt.rst +40 -0
  574. docs/source/_generated/ams.opt.var.Var.rst +45 -0
  575. docs/source/_generated/ams.opt.var.rst +30 -0
  576. docs/source/_generated/ams.routines.dcopf.DCOPF.rst +83 -0
  577. docs/source/_generated/ams.routines.dcopf.rst +30 -0
  578. docs/source/_generated/ams.routines.pflow.PFlow.rst +83 -0
  579. docs/source/_generated/ams.routines.pflow.rst +30 -0
  580. docs/source/_generated/ams.routines.routine.RoutineBase.rst +83 -0
  581. docs/source/_generated/ams.routines.routine.collect_data.rst +6 -0
  582. docs/source/_generated/ams.routines.routine.initialize_data_dict.rst +6 -0
  583. docs/source/_generated/ams.routines.routine.rst +38 -0
  584. docs/source/_generated/ams.system.System.rst +189 -0
  585. docs/source/_generated/ams.system.disable_method.rst +6 -0
  586. docs/source/_generated/ams.system.disable_methods.rst +6 -0
  587. docs/source/_generated/ams.system.example.rst +6 -0
  588. docs/source/_generated/ams.system.rst +39 -0
  589. docs/source/_generated/ams.utils.paths.DisplayablePath.rst +42 -0
  590. docs/source/_generated/ams.utils.paths.ams_root.rst +6 -0
  591. docs/source/_generated/ams.utils.paths.cases_root.rst +6 -0
  592. docs/source/_generated/ams.utils.paths.confirm_overwrite.rst +6 -0
  593. docs/source/_generated/ams.utils.paths.get_case.rst +6 -0
  594. docs/source/_generated/ams.utils.paths.get_config_path.rst +6 -0
  595. docs/source/_generated/ams.utils.paths.get_dot_andes_path.rst +6 -0
  596. docs/source/_generated/ams.utils.paths.get_log_dir.rst +6 -0
  597. docs/source/_generated/ams.utils.paths.get_pkl_path.rst +6 -0
  598. docs/source/_generated/ams.utils.paths.get_pycode_path.rst +6 -0
  599. docs/source/_generated/ams.utils.paths.list_cases.rst +6 -0
  600. docs/source/_generated/ams.utils.paths.rst +47 -0
  601. docs/source/_generated/ams.utils.paths.tests_root.rst +6 -0
  602. docs/source/_templates/autosummary/base.rst +5 -0
  603. docs/source/_templates/autosummary/class.rst +35 -0
  604. docs/source/_templates/autosummary/module.rst +65 -0
  605. docs/source/_templates/autosummary/module_toctree.rst +66 -0
  606. docs/source/api.rst +102 -0
  607. docs/source/conf.py +203 -0
  608. docs/source/examples/index.rst +34 -0
  609. docs/source/genmodelref.py +61 -0
  610. docs/source/genroutineref.py +47 -0
  611. docs/source/getting_started/copyright.rst +20 -0
  612. docs/source/getting_started/formats/index.rst +20 -0
  613. docs/source/getting_started/formats/matpower.rst +183 -0
  614. docs/source/getting_started/formats/psse.rst +46 -0
  615. docs/source/getting_started/formats/pypower.rst +223 -0
  616. docs/source/getting_started/formats/xlsx.png +0 -0
  617. docs/source/getting_started/formats/xlsx.rst +23 -0
  618. docs/source/getting_started/index.rst +76 -0
  619. docs/source/getting_started/install.rst +234 -0
  620. docs/source/getting_started/overview.rst +26 -0
  621. docs/source/getting_started/testcase.rst +45 -0
  622. docs/source/getting_started/verification.rst +13 -0
  623. docs/source/groupdoc/ACLine.rst +92 -0
  624. docs/source/groupdoc/ACShort.rst +51 -0
  625. docs/source/groupdoc/ACTopology.rst +66 -0
  626. docs/source/groupdoc/Collection.rst +84 -0
  627. docs/source/groupdoc/Cost.rst +135 -0
  628. docs/source/groupdoc/DG.rst +204 -0
  629. docs/source/groupdoc/Horizon.rst +97 -0
  630. docs/source/groupdoc/Information.rst +36 -0
  631. docs/source/groupdoc/RenGen.rst +63 -0
  632. docs/source/groupdoc/Reserve.rst +135 -0
  633. docs/source/groupdoc/StaticGen.rst +229 -0
  634. docs/source/groupdoc/StaticLoad.rst +53 -0
  635. docs/source/groupdoc/StaticShunt.rst +45 -0
  636. docs/source/groupdoc/Undefined.rst +63 -0
  637. docs/source/groupdoc/VSG.rst +125 -0
  638. docs/source/images/dcopf_time.png +0 -0
  639. docs/source/images/sponsors/CURENT_Logo_NameOnTrans.png +0 -0
  640. docs/source/images/sponsors/CURENT_Logo_Transparent.png +0 -0
  641. docs/source/images/sponsors/CURENT_Logo_Transparent_Name.png +0 -0
  642. docs/source/images/sponsors/doe.png +0 -0
  643. docs/source/index.rst +108 -0
  644. docs/source/modeling/_generated/_generated/ams.opt.Constraint.class_name.rst +6 -0
  645. docs/source/modeling/_generated/_generated/ams.opt.Constraint.e.rst +6 -0
  646. docs/source/modeling/_generated/_generated/ams.opt.Constraint.evaluate.rst +6 -0
  647. docs/source/modeling/_generated/_generated/ams.opt.Constraint.n.rst +6 -0
  648. docs/source/modeling/_generated/_generated/ams.opt.Constraint.parse.rst +6 -0
  649. docs/source/modeling/_generated/_generated/ams.opt.Constraint.shape.rst +6 -0
  650. docs/source/modeling/_generated/_generated/ams.opt.Constraint.size.rst +6 -0
  651. docs/source/modeling/_generated/_generated/ams.opt.Constraint.v.rst +6 -0
  652. docs/source/modeling/_generated/_generated/ams.opt.OModel.class_name.rst +6 -0
  653. docs/source/modeling/_generated/_generated/ams.opt.OModel.evaluate.rst +6 -0
  654. docs/source/modeling/_generated/_generated/ams.opt.OModel.finalize.rst +6 -0
  655. docs/source/modeling/_generated/_generated/ams.opt.OModel.init.rst +6 -0
  656. docs/source/modeling/_generated/_generated/ams.opt.OModel.initialized.rst +6 -0
  657. docs/source/modeling/_generated/_generated/ams.opt.OModel.parse.rst +6 -0
  658. docs/source/modeling/_generated/_generated/ams.opt.OModel.update.rst +6 -0
  659. docs/source/modeling/_generated/_generated/ams.opt.Objective.class_name.rst +6 -0
  660. docs/source/modeling/_generated/_generated/ams.opt.Objective.e.rst +6 -0
  661. docs/source/modeling/_generated/_generated/ams.opt.Objective.evaluate.rst +6 -0
  662. docs/source/modeling/_generated/_generated/ams.opt.Objective.n.rst +6 -0
  663. docs/source/modeling/_generated/_generated/ams.opt.Objective.parse.rst +6 -0
  664. docs/source/modeling/_generated/_generated/ams.opt.Objective.shape.rst +6 -0
  665. docs/source/modeling/_generated/_generated/ams.opt.Objective.size.rst +6 -0
  666. docs/source/modeling/_generated/_generated/ams.opt.Objective.v.rst +6 -0
  667. docs/source/modeling/_generated/_generated/ams.opt.Var.class_name.rst +6 -0
  668. docs/source/modeling/_generated/_generated/ams.opt.Var.evaluate.rst +6 -0
  669. docs/source/modeling/_generated/_generated/ams.opt.Var.get_idx.rst +6 -0
  670. docs/source/modeling/_generated/_generated/ams.opt.Var.n.rst +6 -0
  671. docs/source/modeling/_generated/_generated/ams.opt.Var.parse.rst +6 -0
  672. docs/source/modeling/_generated/_generated/ams.opt.Var.shape.rst +6 -0
  673. docs/source/modeling/_generated/_generated/ams.opt.Var.size.rst +6 -0
  674. docs/source/modeling/_generated/_generated/ams.opt.Var.v.rst +6 -0
  675. docs/source/modeling/_generated/ams.opt.Constraint.rst +43 -0
  676. docs/source/modeling/_generated/ams.opt.OModel.rst +48 -0
  677. docs/source/modeling/_generated/ams.opt.Objective.rst +43 -0
  678. docs/source/modeling/_generated/ams.opt.Var.rst +45 -0
  679. docs/source/modeling/example.rst +159 -0
  680. docs/source/modeling/index.rst +17 -0
  681. docs/source/modeling/model.rst +210 -0
  682. docs/source/modeling/routine.rst +122 -0
  683. docs/source/modeling/system.rst +51 -0
  684. docs/source/modelref.rst +66 -0
  685. docs/source/release-notes.rst +385 -0
  686. docs/source/routineref.rst +38 -0
  687. docs/source/typedoc/ACED.rst +91 -0
  688. docs/source/typedoc/DCED.rst +1869 -0
  689. docs/source/typedoc/DCUC.rst +899 -0
  690. docs/source/typedoc/DED.rst +390 -0
  691. docs/source/typedoc/PF.rst +376 -0
  692. docs/source/typedoc/UndefinedType.rst +8 -0
  693. icebar/ips/ips.py +668 -0
  694. ltbams-1.0.0.dist-info/METADATA +231 -0
  695. ltbams-1.0.0.dist-info/RECORD +725 -0
  696. {ltbams-0.9.9.dist-info → ltbams-1.0.0.dist-info}/WHEEL +1 -1
  697. ltbams-1.0.0.dist-info/top_level.txt +5 -0
  698. tests/__init__.py +0 -0
  699. tests/test_1st_system.py +33 -0
  700. tests/test_addressing.py +40 -0
  701. tests/test_andes_mats.py +61 -0
  702. tests/test_case.py +266 -0
  703. tests/test_cli.py +34 -0
  704. tests/test_export_csv.py +89 -0
  705. tests/test_group.py +83 -0
  706. tests/test_interface.py +216 -0
  707. tests/test_io.py +32 -0
  708. tests/test_jumper.py +27 -0
  709. tests/test_known_good.py +267 -0
  710. tests/test_matp.py +437 -0
  711. tests/test_model.py +54 -0
  712. tests/test_omodel.py +119 -0
  713. tests/test_paths.py +22 -0
  714. tests/test_report.py +245 -0
  715. tests/test_repr.py +21 -0
  716. tests/test_routine.py +178 -0
  717. tests/test_rtn_dcopf.py +101 -0
  718. tests/test_rtn_dcpf.py +77 -0
  719. tests/test_rtn_ed.py +275 -0
  720. tests/test_rtn_pflow.py +219 -0
  721. tests/test_rtn_rted.py +273 -0
  722. tests/test_rtn_uc.py +248 -0
  723. tests/test_service.py +73 -0
  724. ltbams-0.9.9.dist-info/LICENSE +0 -692
  725. ltbams-0.9.9.dist-info/METADATA +0 -859
  726. ltbams-0.9.9.dist-info/RECORD +0 -14
  727. ltbams-0.9.9.dist-info/top_level.txt +0 -1
  728. {ltbams-0.9.9.dist-info → ltbams-1.0.0.dist-info}/entry_points.txt +0 -0
ams/interface.py ADDED
@@ -0,0 +1,1085 @@
1
+ """
2
+ Module for interfacing ANDES
3
+ """
4
+
5
+ import os
6
+ import logging
7
+ from collections import OrderedDict, Counter
8
+
9
+ from andes.utils.misc import elapsed
10
+ from andes.system import System as andes_System
11
+
12
+ from ams.utils import create_entry
13
+ from ams.io import input_formats
14
+ from ams.shared import nan, pd, np
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ # Models used in ANDES PFlow
20
+ # FIXME: add DC models, e.g. Node
21
+ pflow_dict = OrderedDict([
22
+ ('Bus', create_entry('Vn', 'vmax', 'vmin', 'v0', 'a0',
23
+ 'xcoord', 'ycoord', 'area', 'zone',
24
+ 'owner')),
25
+ ('PQ', create_entry('bus', 'Vn', 'p0', 'q0', 'vmax',
26
+ 'vmin', 'owner')),
27
+ ('PV', create_entry('Sn', 'Vn', 'bus', 'busr', 'p0', 'q0',
28
+ 'pmax', 'pmin', 'qmax', 'qmin',
29
+ 'v0', 'vmax', 'vmin', 'ra', 'xs')),
30
+ ('Slack', create_entry('Sn', 'Vn', 'bus', 'busr', 'p0', 'q0',
31
+ 'pmax', 'pmin', 'qmax', 'qmin',
32
+ 'v0', 'vmax', 'vmin', 'ra', 'xs', 'a0')),
33
+ ('Shunt', create_entry('Sn', 'Vn', 'bus', 'g', 'b', 'fn')),
34
+ ('Line', create_entry('bus1', 'bus2', 'Sn', 'fn', 'Vn1', 'Vn2',
35
+ 'r', 'x', 'b', 'g', 'b1', 'g1', 'b2', 'g2',
36
+ 'trans', 'tap', 'phi', 'rate_a', 'rate_b',
37
+ 'rate_c', 'owner', 'xcoord', 'ycoord')),
38
+ ('Area', create_entry()),
39
+ ('Jumper', create_entry('bus1', 'bus2')),
40
+ ])
41
+
42
+ # dict for guessing dynamic models given its idx
43
+ idx_guess = {'rego': 'RenGovernor',
44
+ 'ree': 'RenExciter',
45
+ 'rea': 'RenAerodynamics',
46
+ 'rep': 'RenPitch',
47
+ 'busf': 'BusFreq',
48
+ 'zone': 'Zone',
49
+ 'gen': 'StaticGen',
50
+ 'pq': 'PQ',
51
+ 'vsg': 'VSG',
52
+ 'regc': 'VSG', }
53
+
54
+
55
+ def sync_adsys(amsys, adsys):
56
+ """
57
+ Sync parameters value of PFlow models between AMS and ANDES systems.
58
+
59
+ Parameters
60
+ ----------
61
+ amsys : AMS.system.System
62
+ The AMS system.
63
+ adsys : ANDES.system.System
64
+ The ANDES system.
65
+
66
+ Returns
67
+ -------
68
+ bool
69
+ True if successful.
70
+ """
71
+ for mname, params in pflow_dict.items():
72
+ ad_mdl = adsys.__dict__[mname]
73
+ am_mdl = amsys.__dict__[mname]
74
+ idx = am_mdl.idx.v
75
+ for param in params:
76
+ if param in ['idx', 'name']:
77
+ continue
78
+ # NOTE: when setting list values to DataParam, sometimes run into error
79
+ try:
80
+ ad_mdl.set(src=param, attr='v', idx=idx,
81
+ value=am_mdl.get(src=param, attr='v', idx=idx))
82
+ except Exception:
83
+ continue
84
+ return True
85
+
86
+
87
+ def _to_andes_pflow(system, no_output=False, default_config=True, **kwargs):
88
+ """
89
+ Helper function to convert the AMS system to an ANDES system with only
90
+ power flow models.
91
+ """
92
+
93
+ adsys = andes_System(no_outpu=no_output, default_config=default_config, **kwargs)
94
+ # FIXME: is there a systematic way to do this? Other config might be needed
95
+ adsys.config.freq = system.config.freq
96
+ adsys.config.mva = system.config.mva
97
+
98
+ for mdl_name, mdl_cols in pflow_dict.items():
99
+ mdl = getattr(system, mdl_name)
100
+ mdl.cache.refresh("df_in") # refresh cache
101
+ for row in mdl.cache.df_in[mdl_cols].to_dict(orient='records'):
102
+ adsys.add(mdl_name, row)
103
+
104
+ sync_adsys(amsys=system, adsys=adsys)
105
+
106
+ return adsys
107
+
108
+
109
+ def to_andes(system, addfile=None,
110
+ setup=False, no_output=False,
111
+ default_config=True,
112
+ verify=False, tol=1e-3,
113
+ **kwargs):
114
+ """
115
+ Convert the AMS system to an ANDES system.
116
+
117
+ A preferred dynamic system file to be added has following features:
118
+ 1. The file contains both power flow and dynamic models.
119
+ 2. The file can run in ANDES natively.
120
+ 3. Power flow models are in the same shape as the AMS system.
121
+ 4. Dynamic models, if any, are in the same shape as the AMS system.
122
+
123
+ This function is wrapped as the ``System`` class method ``to_andes()``.
124
+ Using the file conversion ``to_andes()`` will automatically
125
+ link the AMS system instance to the converted ANDES system instance
126
+ in the AMS system attribute ``dyn``.
127
+
128
+ It should be noted that detailed dynamic simualtion requires extra
129
+ dynamic models to be added to the ANDES system, which can be passed
130
+ through the ``addfile`` argument.
131
+
132
+ Parameters
133
+ ----------
134
+ system : System
135
+ The AMS system to be converted to ANDES format.
136
+ addfile : str, optional
137
+ The additional file to be converted to ANDES dynamic mdoels.
138
+ setup : bool, optional
139
+ Whether to call `setup()` after the conversion. Default is True.
140
+ no_output : bool, optional
141
+ To ANDES system.
142
+ default_config : bool, optional
143
+ To ANDES system.
144
+ verify : bool
145
+ If True, the converted ANDES system will be verified with the source
146
+ AMS system using AC power flow.
147
+ tol : float
148
+ The tolerance of error.
149
+
150
+ Returns
151
+ -------
152
+ adsys : andes.system.System
153
+ The converted ANDES system.
154
+
155
+ Examples
156
+ --------
157
+ >>> import ams
158
+ >>> import andes
159
+ >>> sp = ams.load(ams.get_case('ieee14/ieee14_uced.xlsx'), setup=True)
160
+ >>> sa = sp.to_andes(addfile=andes.get_case('ieee14/ieee14_full.xlsx'),
161
+ ... setup=False, overwrite=True, no_output=True)
162
+
163
+ Notes
164
+ -----
165
+ 1. Power flow models in the addfile will be skipped and only dynamic models will be used.
166
+ 2. The addfile format is guessed based on the file extension. Currently only ``xlsx`` is supported.
167
+ 3. Index in the addfile is automatically adjusted when necessary.
168
+ """
169
+ t0, _ = elapsed()
170
+
171
+ # --- convert power flow models ---
172
+ adsys = _to_andes_pflow(system, no_output=no_output, default_config=default_config, **kwargs)
173
+
174
+ _, s = elapsed(t0)
175
+
176
+ # additonal file for dynamic models
177
+ if addfile:
178
+ t_add, _ = elapsed()
179
+
180
+ # --- parse addfile ---
181
+ adsys = parse_addfile(adsys=adsys, amsys=system, addfile=addfile)
182
+
183
+ _, s_add = elapsed(t_add)
184
+ logger.info('Addfile parsed in %s.', s_add)
185
+
186
+ # fake FileManaer attributes
187
+ adsys.files = system.files
188
+
189
+ logger.info(f'System converted to ANDES in {s}.')
190
+
191
+ # finalize
192
+ system.dyn = Dynamic(amsys=system, adsys=adsys)
193
+ system.dyn.link_andes(adsys=adsys)
194
+
195
+ if setup:
196
+ adsys.setup()
197
+ elif verify:
198
+ logger.warning('PFlow verification is skipped due to no setup.')
199
+ return adsys
200
+ if verify:
201
+ verify_pf(amsys=system, adsys=adsys, tol=tol)
202
+ return adsys
203
+
204
+
205
+ def parse_addfile(adsys, amsys, addfile):
206
+ """
207
+ Parse the addfile for ANDES dynamic file.
208
+
209
+ Parameters
210
+ ----------
211
+ adsys : andes.system.System
212
+ The ANDES system instance.
213
+ amsys : ams.system.System
214
+ The AMS system instance.
215
+ addfile : str
216
+ The additional file to be converted to ANDES dynamic mdoels.
217
+
218
+ Returns
219
+ -------
220
+ adsys : andes.system.System
221
+ The ANDES system instance with dynamic models added.
222
+ """
223
+ # guess addfile format
224
+ add_format = None
225
+ _, add_ext = os.path.splitext(addfile)
226
+ for key, val in input_formats.items():
227
+ if add_ext[1:] in val:
228
+ add_format = key
229
+ logger.debug('Addfile format guessed as %s.', key)
230
+ break
231
+
232
+ if key != 'xlsx':
233
+ logger.error('Addfile format "%s" is not supported yet.', add_format)
234
+ # FIXME: xlsx input file with dyr addfile result into KeyError: 'Toggle'
235
+ # add_parser = importlib.import_module('andes.io.' + add_format)
236
+ # if not add_parser.read_add(system, addfile):
237
+ # logger.error('Error parsing addfile "%s" with %s parser.', addfile, add_format)
238
+ return adsys
239
+
240
+ # Try parsing the addfile
241
+ logger.info('Parsing additional file "%s"...', addfile)
242
+
243
+ reader = pd.ExcelFile(addfile)
244
+
245
+ pflow_mdl = list(pflow_dict.keys())
246
+
247
+ pflow_mdls_overlap = []
248
+ for mdl_name in pflow_dict.keys():
249
+ if mdl_name in reader.sheet_names:
250
+ pflow_mdls_overlap.append(mdl_name)
251
+
252
+ if len(pflow_mdls_overlap) > 0:
253
+ msg = 'Following PFlow models in addfile will be overwritten: '
254
+ msg += ', '.join([f'<{mdl}>' for mdl in pflow_mdls_overlap])
255
+ logger.warning(msg)
256
+
257
+ pflow_mdl_nonempty = [mdl for mdl in pflow_mdl if amsys.models[mdl].n > 0]
258
+ logger.debug(f"Non-empty PFlow models: {pflow_mdl}")
259
+ pflow_df_models = pd.read_excel(addfile,
260
+ sheet_name=pflow_mdl_nonempty,
261
+ index_col=0,
262
+ engine='openpyxl',
263
+ )
264
+ # drop rows that all nan
265
+ for name, df in pflow_df_models.items():
266
+ df.dropna(axis=0, how='all', inplace=True)
267
+
268
+ # collect idx_map if difference exists
269
+ idx_map = OrderedDict([])
270
+ for name, df in pflow_df_models.items():
271
+ am_idx = amsys.models[name].idx.v
272
+ ad_idx = df['idx'].values
273
+ if len(set(am_idx)) != len(set(ad_idx)):
274
+ msg = f'<{name}> has different number of rows in addfile.'
275
+ logger.warning(msg)
276
+ if set(am_idx) != set(ad_idx):
277
+ idx_map[name] = dict(zip(ad_idx, am_idx))
278
+
279
+ # --- dynamic models to be added ---
280
+ mdl_to_keep = list(set(reader.sheet_names) - set(pflow_mdl))
281
+ mdl_to_keep.sort(key=str.lower)
282
+ df_models = pd.read_excel(addfile,
283
+ sheet_name=mdl_to_keep,
284
+ index_col=0,
285
+ engine='openpyxl',
286
+ )
287
+
288
+ # adjust models index
289
+ for name, df in df_models.items():
290
+ try:
291
+ mdl = adsys.models[name]
292
+ except KeyError:
293
+ mdl = adsys.model_aliases[name]
294
+ if len(mdl.idx_params) == 0: # skip if no idx_params
295
+ continue
296
+ for idxn, idxp in mdl.idx_params.items():
297
+ if idxp.model is None: # make a guess if no model is specified
298
+ mdl_guess = idxn.capitalize()
299
+ if mdl_guess not in adsys.models.keys():
300
+ try:
301
+ mdl_guess = idx_guess[idxp.name]
302
+ except KeyError: # set the most frequent string as the model name
303
+ split_list = []
304
+ for item in df[idxn].values:
305
+ if item is None or nan:
306
+ continue
307
+ try:
308
+ split_list.append(item.split('_'))
309
+ # Flatten the nested list and filter non-numerical strings
310
+ flattened_list = [item for sublist in split_list for item in sublist
311
+ if not isinstance(item, int)]
312
+ # Count the occurrences of non-numerical strings
313
+ string_counter = Counter(flattened_list)
314
+ # Find the most common non-numerical string
315
+ mdl_guess = string_counter.most_common(1)[0][0]
316
+ except AttributeError:
317
+ logger.error(f'Failed to parse IdxParam {name}.{idxn}.')
318
+ continue
319
+ else:
320
+ mdl_guess = idxp.model
321
+ if mdl_guess in adsys.groups.keys():
322
+ grp_idx = {}
323
+ for mname, mdl in adsys.groups[mdl_guess].models.items():
324
+ # add group index to index map
325
+ if mname in idx_map.keys():
326
+ grp_idx.update(idx_map[mname])
327
+ if len(grp_idx) == 0:
328
+ continue # no index consistency issue, skip
329
+ idx_map[mdl_guess] = grp_idx
330
+ if mdl_guess not in idx_map.keys():
331
+ continue # no index consistency issue, skip
332
+ else:
333
+ logger.debug(f'Replace map for {mdl_guess} is {idx_map[mdl_guess]}')
334
+ df[idxn] = df[idxn].replace(idx_map[mdl_guess])
335
+ logger.debug(f'Adjust {idxp.class_name} <{name}.{idxp.name}>')
336
+
337
+ # NOTE: Group TimedEvent needs special treatment
338
+ # adjust Toggle and Fault models
339
+ toggle_df = df_models.get('Toggle') or df_models.get('Toggler')
340
+ if toggle_df is not None:
341
+ toggle_df['dev'] = toggle_df.apply(replace_dev, axis=1,
342
+ mdl='model', dev='dev',
343
+ idx_map=idx_map)
344
+
345
+ alter_df = df_models.get('Alter')
346
+ if alter_df is not None:
347
+ alter_df['dev'] = alter_df.apply(replace_dev, axis=1,
348
+ mdl='model', dev='dev',
349
+ idx_map=idx_map)
350
+
351
+ # adjust Fault model
352
+ fault_df = df_models.get('Fault')
353
+ if fault_df is not None:
354
+ fault_df['bus'] = fault_df.apply(replace_dev, axis=1,
355
+ mdl='bus', dev='bus',
356
+ idx_map=idx_map)
357
+
358
+ # add dynamic models
359
+ for name, df in df_models.items():
360
+ # drop rows that all nan
361
+ df.replace(['', ' '], nan, inplace=True) # replace empty string with nan
362
+ df.dropna(axis=0, how='all', inplace=True)
363
+ # if the dynamic model also exists in AMS, use AMS parameters for overlap
364
+ if (name in amsys.models.keys()) and amsys.models[name].n > 0:
365
+ if df.shape[0] != amsys.models[name].n:
366
+ msg = f'<{name}> has different number of rows in addfile.'
367
+ logger.warning(msg)
368
+ am_params = set(amsys.models[name].params.keys())
369
+ ad_params = set(df.columns)
370
+ overlap_params = list(am_params.intersection(ad_params))
371
+ ad_rest_params = list(ad_params - am_params) + ['idx']
372
+ msg = f'Following <{name}> parameters in addfile are overwriten: '
373
+ msg += ', '.join(overlap_params)
374
+ logger.debug(msg)
375
+ tmp = amsys.models[name].cache.df_in[overlap_params]
376
+ df = pd.merge(left=tmp, right=df[ad_rest_params],
377
+ on='idx', how='left')
378
+ for row in df.to_dict(orient='records'):
379
+ adsys.add(name, row)
380
+
381
+ # --- adjust SynGen Vn with Bus Vn ---
382
+ # NOTE: RenGen and DG have no Vn, so no need to adjust
383
+ syg_idx = []
384
+ for _, syg in adsys.SynGen.models.items():
385
+ if syg.n > 0:
386
+ syg_idx += syg.idx.v
387
+ syg_bus_idx = adsys.SynGen.get(src='bus', attr='v', idx=syg_idx)
388
+ syg_bus_vn = adsys.Bus.get(src='Vn', idx=syg_bus_idx)
389
+ adsys.SynGen.set(src='Vn', idx=syg_idx, attr='v', value=syg_bus_vn)
390
+
391
+ # --- for debugging ---
392
+ adsys.df_in = df_models
393
+
394
+ return adsys
395
+
396
+
397
+ class Dynamic:
398
+ """
399
+ ANDES interface class.
400
+
401
+ Parameters
402
+ ----------
403
+ amsys : AMS.system.System
404
+ The AMS system.
405
+ adsys : ANDES.system.System
406
+ The ANDES system.
407
+
408
+ Attributes
409
+ ----------
410
+ link : pandas.DataFrame
411
+ The ANDES system link table.
412
+
413
+ Notes
414
+ -----
415
+ 1. Using the file conversion ``to_andes()`` will automatically
416
+ link the AMS system to the converted ANDES system in the
417
+ attribute ``dyn``.
418
+
419
+ Examples
420
+ --------
421
+ >>> import ams
422
+ >>> import andes
423
+ >>> sp = ams.load(ams.get_case('ieee14/ieee14_rted.xlsx'), setup=True)
424
+ >>> sa = sp.to_andes(setup=True,
425
+ ... addfile=andes.get_case('ieee14/ieee14_wt3.xlsx'),
426
+ ... overwrite=True, keep=False, no_output=True)
427
+ >>> sp.RTED.run()
428
+ >>> sp.RTED.dc2ac()
429
+ >>> sp.dyn.send() # send RTED results to ANDES system
430
+ >>> sa.PFlow.run()
431
+ >>> sp.TDS.run()
432
+ >>> sp.dyn.receive() # receive TDS results from ANDES system
433
+ """
434
+
435
+ def __init__(self, amsys=None, adsys=None) -> None:
436
+ self.amsys = amsys # AMS system
437
+ self.adsys = adsys # ANDES system
438
+
439
+ # TODO: add summary table
440
+ self.link = None # ANDES system link table
441
+
442
+ def link_andes(self, adsys):
443
+ """
444
+ Link the ANDES system to the AMS system.
445
+
446
+ Parameters
447
+ ----------
448
+ adsys : ANDES.system.System
449
+ The ANDES system instance.
450
+ """
451
+ self.adsys = adsys
452
+
453
+ self.link = make_link_table(self.adsys)
454
+ logger.warning(f'AMS system {hex(id(self.amsys))} is linked to the ANDES system {hex(id(adsys))}.')
455
+
456
+ @property
457
+ def is_tds(self):
458
+ """
459
+ Indicator of whether the ANDES system is running a TDS.
460
+ This property will return ``True`` as long as TDS is initialized.
461
+
462
+ Check ``adsys.tds.TDS.init()`` for more details.
463
+ """
464
+ return bool(self.adsys.TDS.initialized)
465
+
466
+ def _send_tgr(self, sa, sp):
467
+ """
468
+ Sned to generator power refrence.
469
+
470
+ Notes
471
+ -----
472
+ 1. AGC power reference ``paux`` is not included in this function.
473
+ """
474
+ # 1) TurbineGov
475
+ syg_idx = sp.dyn.link['syg_idx'].dropna().tolist() # SynGen idx
476
+ # corresponding StaticGen idx in ANDES
477
+ stg_syg_idx = sa.SynGen.get(src='gen', attr='v', idx=syg_idx,
478
+ allow_none=True, default=None)
479
+ # corresponding TurbineGov idx in ANDES
480
+ gov_idx = sa.TurbineGov.find_idx(keys='syn', values=syg_idx)
481
+ # corresponding StaticGen pg in AMS
482
+ syg_ams = sp.recent.get(src='pg', attr='v', idx=stg_syg_idx,
483
+ allow_none=True, default=0)
484
+ # --- check consistency ---
485
+ syg_mask = self.link['syg_idx'].notnull() & self.link['gov_idx'].isnull()
486
+ if syg_mask.any():
487
+ logger.debug('Governor is not complete for SynGen.')
488
+ # --- pref ---
489
+ sa.TurbineGov.set(value=syg_ams, idx=gov_idx, attr='v', src='pref0')
490
+
491
+ # --- paux ---
492
+ # TODO: sync paux, using paux0
493
+
494
+ # 2) DG
495
+ dg_idx = sp.dyn.link['dg_idx'].dropna().tolist() # DG idx
496
+ # corresponding StaticGen idx in ANDES
497
+ stg_dg_idx = sa.DG.get(src='gen', attr='v', idx=dg_idx,
498
+ allow_none=True, default=None,
499
+ )
500
+ # corresponding StaticGen pg in AMS
501
+ dg_ams = sp.recent.get(src='pg', attr='v', idx=stg_dg_idx,
502
+ allow_none=True, default=0)
503
+ # --- pref ---
504
+ sa.DG.set(src='pref0', idx=dg_idx, attr='v', value=dg_ams)
505
+ # TODO: paux, using Pext0, this one should be do in other place rather than here
506
+
507
+ # 3) RenGen
508
+ # TODO: seems to be unnecessary
509
+ # which models/params are used to control output and auxillary power?
510
+
511
+ return True
512
+
513
+ def _send_dgu(self, sa, sp):
514
+ """
515
+ Send to ANDES the dynamic generator online status.
516
+ """
517
+ # 1) SynGen
518
+ syg_idx = sp.dyn.link['syg_idx'].dropna().tolist() # SynGen idx
519
+ # corresponding StaticGen idx in ANDES
520
+ stg_syg_idx = sa.SynGen.get(src='gen', attr='v', idx=syg_idx,
521
+ allow_none=True, default=None)
522
+ # corresponding StaticGen u in AMS
523
+ stg_u_ams = sp.StaticGen.get(src='u', attr='v', idx=stg_syg_idx,
524
+ allow_none=True, default=0)
525
+ stg_u_andes = sa.SynGen.get(src='u', attr='v', idx=syg_idx,
526
+ allow_none=True, default=0)
527
+ # 2) DG
528
+ dg_idx = sp.dyn.link['dg_idx'].dropna().tolist() # DG idx
529
+ # corresponding StaticGen idx in ANDES
530
+ stg_dg_idx = sa.DG.get(src='gen', attr='v', idx=dg_idx,
531
+ allow_none=True, default=None)
532
+ # corresponding DG u in AMS
533
+ dg_u_ams = sp.StaticGen.get(src='u', attr='v', idx=stg_dg_idx,
534
+ allow_none=True, default=0)
535
+ du_u_andes = sa.DG.get(src='u', attr='v', idx=dg_idx,
536
+ allow_none=True, default=0)
537
+ # 3) RenGen
538
+ rg_idx = sp.dyn.link['rg_idx'].dropna().tolist() # RenGen idx
539
+ # corresponding StaticGen idx in ANDES
540
+ stg_rg_idx = sa.RenGen.get(src='gen', attr='v', idx=rg_idx,
541
+ allow_none=True, default=None)
542
+ # corresponding RenGen u in AMS
543
+ rg_u_ams = sp.StaticGen.get(src='u', attr='v', idx=stg_rg_idx,
544
+ allow_none=True, default=0)
545
+ rg_u_andes = sa.RenGen.get(src='u', attr='v', idx=rg_idx,
546
+ allow_none=True, default=0)
547
+ # 4) sync results
548
+ cond = (
549
+ not np.array_equal(stg_u_ams, stg_u_andes) or
550
+ not np.array_equal(dg_u_ams, du_u_andes) or
551
+ not np.array_equal(rg_u_ams, rg_u_andes)
552
+ )
553
+ if cond:
554
+ msg = 'ANDES dynamic generator online status should be switched using Toggle!'
555
+ msg += ' Otherwise, unexpected results might occur.'
556
+ raise ValueError(msg)
557
+ # FIXME: below code seems to be unnecessary
558
+ sa.SynGen.set(src='u', idx=syg_idx, attr='v', value=stg_u_ams)
559
+ sa.DG.set(src='u', idx=dg_idx, attr='v', value=dg_u_ams)
560
+ sa.RenGen.set(src='u', idx=rg_idx, attr='v', value=rg_u_ams)
561
+ return True
562
+
563
+ def _sync_check(self, amsys, adsys):
564
+ """
565
+ Check if AMS and ANDES systems are ready for sync.
566
+ """
567
+ if amsys.dyn.adsys:
568
+ if amsys.dyn.adsys != adsys:
569
+ logger.error('Target ANDES system is different from the linked one, quit.')
570
+ return False
571
+ if not amsys.is_setup:
572
+ amsys.setup()
573
+ if not adsys.is_setup:
574
+ adsys.setup()
575
+ if amsys.dyn.link is None:
576
+ amsys.dyn.link = make_link_table(adsys=adsys)
577
+
578
+ def send(self, adsys=None, routine=None):
579
+ """
580
+ Send results of the recent sovled AMS routine (``sp.recent``) to the
581
+ target ANDES system.
582
+
583
+ Note that converged AC conversion DOES NOT guarantee successful dynamic
584
+ initialization ``TDS.init()``.
585
+ Failed initialization is usually caused by limiter violation.
586
+
587
+ Parameters
588
+ ----------
589
+ adsys : adsys.System.system, optional
590
+ The target ANDES dynamic system instance. If not provided, use the
591
+ linked ANDES system isntance (``sp.dyn.adsys``).
592
+ routine : str, optional
593
+ The routine to be sent to ANDES. If None, ``recent`` will be used.
594
+ """
595
+ sa = adsys if adsys is not None else self.adsys
596
+ sp = self.amsys
597
+ self._sync_check(amsys=sp, adsys=sa)
598
+
599
+ # --- Information ---
600
+ rtn = sp.recent if routine is None else getattr(sp, routine)
601
+ if rtn is None:
602
+ logger.warning('No assigned or recent solved routine found, quit send.')
603
+ return False
604
+ elif rtn.exit_code != 0:
605
+ logger.warning(f'{sp.recent.class_name} is not solved at optimal, quit send.')
606
+ return False
607
+ else:
608
+ logger.info(f'Send <{rtn.class_name}> results to ANDES <{hex(id(sa))}>...')
609
+
610
+ # NOTE: if DC type, check if results are converted
611
+ if (rtn.type != 'ACED') and (not rtn.converted):
612
+ logger.error(f'<{rtn.class_name}> AC conversion failed or not done yet!')
613
+
614
+ # --- Mapping ---
615
+ map2 = getattr(rtn, 'map2') # mapping-to dict
616
+ if len(map2) == 0:
617
+ logger.warning(f'{rtn.class_name} has empty map2, quit send.')
618
+ return True
619
+
620
+ # NOTE: ads is short for ANDES
621
+ for vname_ams, (mname_ads, pname_ads) in map2.items():
622
+ mdl_ads = getattr(sa, mname_ads) # ANDES model or group
623
+
624
+ # --- skipping scenarios ---
625
+ if mdl_ads.n == 0:
626
+ logger.debug(f'ANDES model <{mname_ads}> is empty.')
627
+ continue
628
+
629
+ var_ams = getattr(rtn, vname_ams) # instance of AMS routine var
630
+ idx_ads = var_ams.get_all_idxes() # use AMS idx as target ANDES idx
631
+
632
+ # --- special scenarios ---
633
+ # 0. send PV bus voltage to StaticGen.v0 if not PFlow yet and AC converted
634
+ cond_vpv = (mname_ads == 'Bus') and (pname_ads == 'v0')
635
+ if cond_vpv and (not self.is_tds) and (rtn.converted):
636
+ # --- StaticGen ---
637
+ stg_idx = sp.StaticGen.get_all_idxes()
638
+ bus_stg = sp.StaticGen.get(src='bus', attr='v', idx=stg_idx)
639
+ vBus = rtn.get(src='vBus', attr='v', idx=bus_stg)
640
+ sa.StaticGen.set(src='v0', idx=stg_idx, attr='v', value=vBus)
641
+ logger.info(f'*Send <{vname_ams}> to StaticGen.v0')
642
+
643
+ # 1. gen online status; in TDS running, setting u is invalid
644
+ cond_ads_stg_u = (mname_ads in ['StaticGen', 'PV', 'Sclak']) and (pname_ads == 'u')
645
+ if cond_ads_stg_u and (self.is_tds):
646
+ logger.info(f'*Skip sending {vname_ams} to StaticGen.u during TDS')
647
+ continue
648
+
649
+ # 2. Bus voltage
650
+ cond_ads_bus_v0 = (mname_ads == 'Bus') and (pname_ads == 'v0')
651
+ if cond_ads_bus_v0 and (self.is_tds):
652
+ logger.info(f'*Skip sending {vname_ams} t0 Bus.v0 during TDS')
653
+ continue
654
+
655
+ # 3. gen power reference; in TDS running, pg should go to TurbineGov
656
+ cond_ads_stg_p0 = (mname_ads in ['StaticGen', 'PV', 'Sclak']) and (pname_ads == 'p0')
657
+ if cond_ads_stg_p0 and (self.is_tds):
658
+ # --- SynGen: TurbineGov.pref0 ---
659
+ syg_idx = sp.dyn.link['syg_idx'].dropna().tolist() # SynGen idx
660
+ # corresponding StaticGen idx in ANDES
661
+ stg_syg_idx = sa.SynGen.get(src='gen', attr='v', idx=syg_idx,
662
+ allow_none=True, default=None)
663
+ # corresponding TurbineGov idx in ANDES
664
+ gov_idx = sa.TurbineGov.find_idx(keys='syn', values=syg_idx)
665
+ # corresponding StaticGen pg in AMS
666
+ syg_ams = rtn.get(src='pg', attr='v', idx=stg_syg_idx)
667
+ # NOTE: check consistency
668
+ syg_mask = self.link['syg_idx'].notnull() & self.link['gov_idx'].isnull()
669
+ if syg_mask.any():
670
+ logger.debug('Governor is not complete for SynGen.')
671
+ # --- pref ---
672
+ sa.TurbineGov.set(src='pref0', idx=gov_idx, attr='v', value=syg_ams)
673
+
674
+ # --- DG: DG.pref0 ---
675
+ dg_idx = sp.dyn.link['dg_idx'].dropna().tolist() # DG idx
676
+ # corresponding StaticGen idx in ANDES
677
+ stg_dg_idx = sa.DG.get(src='gen', attr='v', idx=dg_idx,
678
+ allow_none=True, default=None)
679
+ # corresponding StaticGen pg in AMS
680
+ dg_ams = rtn.get(src='pg', attr='v', idx=stg_dg_idx)
681
+ # --- pref ---
682
+ sa.DG.set(src='pref0', idx=dg_idx, attr='v', value=dg_ams)
683
+
684
+ # --- RenGen: seems unnecessary ---
685
+ # TODO: which models/params are used to control output and auxillary power?
686
+
687
+ var_dest = ''
688
+ if len(syg_ams) > 0:
689
+ var_dest = 'TurbineGov.pref0'
690
+ if len(dg_ams) > 0:
691
+ var_dest += ' and DG.pref0'
692
+ logger.warning(f'*Send <{vname_ams}> to {var_dest}')
693
+ continue
694
+
695
+ # --- other scenarios ---
696
+ if _dest_check(mname=mname_ads, pname=pname_ads, idx=idx_ads, adsys=sa):
697
+ mdl_ads.set(src=pname_ads, idx=idx_ads, attr='v', value=var_ams.v)
698
+ logger.warning(f'Send <{vname_ams}> to {mname_ads}.{pname_ads}')
699
+ return True
700
+
701
+ def receive(self, adsys=None, routine=None, no_update=False):
702
+ """
703
+ Receive ANDES system results to AMS devices.
704
+
705
+ Parameters
706
+ ----------
707
+ adsys : adsys.System.system, optional
708
+ The target ANDES dynamic system instance. If not provided, use the
709
+ linked ANDES system isntance (``sp.dyn.adsys``).
710
+ routine : str, optional
711
+ The routine to be received from ANDES. If None, ``recent`` will be used.
712
+ no_update : bool, optional
713
+ True to skip update the AMS routine parameters after sync. Default is False.
714
+ """
715
+ sa = adsys if adsys is not None else self.adsys
716
+ sp = self.amsys
717
+ self._sync_check(amsys=sp, adsys=sa)
718
+
719
+ # --- Information: not necessary in receive ---
720
+ rtn = sp.recent if routine is None else getattr(sp, routine)
721
+ if rtn is None:
722
+ logger.warning('No assigned or recent solved routine found, quit receive.')
723
+ return False
724
+
725
+ # --- Mapping ---
726
+ map1 = getattr(rtn, 'map1') # mapping-from dict
727
+ if len(map1) == 0:
728
+ logger.warning(f'{rtn.class_name} has empty map1, quit receive.')
729
+ return True
730
+
731
+ link = sp.dyn.link # link table
732
+ pname_to_update = [] # list of parameters to be updated
733
+ for vname_ams, (mname_ads, pname_ads) in map1.items():
734
+ mdl_ads = getattr(sa, mname_ads) # ANDES model or group
735
+
736
+ # --- skipping scenarios ---
737
+ if mdl_ads.n == 0:
738
+ logger.debug(f'ANDES model <{mname_ads}> is empty.')
739
+ continue
740
+
741
+ idx_ads = rtn.__dict__[vname_ams].get_all_idxes() # use AMS idx as target ANDES idx
742
+
743
+ # --- special scenarios ---
744
+ # 1. gen online status; in TDS running, take from dynamic generator
745
+ cond_ads_stg_u = (mname_ads in ['StaticGen', 'PV', 'Sclak']) and (pname_ads == 'u')
746
+ if cond_ads_stg_u and (self.is_tds):
747
+ # --- SynGen ---
748
+ u_sg = sa.SynGen.get(idx=link['syg_idx'].replace(nan, None).to_list(),
749
+ src='u', attr='v',
750
+ allow_none=True, default=0,)
751
+ # --- DG ---
752
+ u_dg = sa.DG.get(idx=link['dg_idx'].replace(nan, None).to_list(),
753
+ src='u', attr='v',
754
+ allow_none=True, default=0,)
755
+ # --- RenGen ---
756
+ u_rg = sa.RenGen.get(idx=link['rg_idx'].replace(nan, None).to_list(),
757
+ src='u', attr='v',
758
+ allow_none=True, default=0,)
759
+ # --- output ---
760
+ u_dyg = u_sg + u_rg + u_dg
761
+ # NOTE: StaticGen that has no dynamic generator
762
+ # Sync StaticGen.u first, then overwrite the ones with dynamic generator
763
+ u_stg = sa.StaticGen.get(src='u', attr='v',
764
+ idx=link['stg_idx'].values)
765
+ # NOTE: only update u if changed actually
766
+ u0_rtn = rtn.get(src=vname_ams, attr='v', idx=link['stg_idx'].values).copy()
767
+ rtn.set(src=vname_ams, idx=link['stg_idx'].values, attr='v', value=u_stg)
768
+ rtn.set(src=vname_ams, idx=link['stg_idx'].values, attr='v', value=u_dyg)
769
+ u_rtn = rtn.get(src=vname_ams, attr='v', idx=link['stg_idx'].values).copy()
770
+ if not np.array_equal(u0_rtn, u_rtn):
771
+ pname_to_update.append(vname_ams)
772
+ var_dest = ''
773
+ var_dest += 'SynGen.u' if sa.SynGen.n > 0 else ''
774
+ var_dest += ', DG.u' if sa.DG.n > 0 else ''
775
+ var_dest += ', RenGen.u' if sa.RenGen.n > 0 else ''
776
+ var_dest += ', StaicGen.u' if sa.RenGen.n+sa.SynGen.n+sa.DG.n < sa.StaticGen.n else ''
777
+ logger.info(f'Receive <{vname_ams}> from {var_dest}')
778
+ continue
779
+
780
+ # 2. gen output power; in TDS running, take from dynamic generator
781
+ cond_ads_stg_p = (mname_ads in ['StaticGen', 'PV', 'Sclak']) and (pname_ads == 'p')
782
+ if cond_ads_stg_p and (self.is_tds):
783
+ # --- SynGen ---
784
+ p_sg = sa.SynGen.get(idx=link['syg_idx'].replace(nan, None).to_list(),
785
+ src='Pe', attr='v',
786
+ allow_none=True, default=0,)
787
+ # --- DG ---
788
+ Ie_dg = sa.DG.get(idx=link['dg_idx'].replace(nan, None).to_list(),
789
+ src='Ipout_y', attr='v',
790
+ allow_none=True, default=0,)
791
+ v_dg = sa.DG.get(idx=link['dg_idx'].replace(nan, None).to_list(),
792
+ src='v', attr='v',
793
+ allow_none=True, default=0,)
794
+ p_dg = Ie_dg * v_dg
795
+ # --- RenGen ---
796
+ p_rg = sa.RenGen.get(idx=link['rg_idx'].replace(nan, None).to_list(),
797
+ src='Pe', attr='v',
798
+ allow_none=True, default=0,)
799
+ # --- output ---
800
+ p_dyg = p_sg + p_rg + p_dg
801
+ # NOTE: StaticGen that has no dynamic generator
802
+ # Sync StaticGen.p first, then overwrite the ones with dynamic generator
803
+ p_stg = sa.StaticGen.get(src='p', attr='v',
804
+ idx=link['stg_idx'].values)
805
+ rtn.set(src=vname_ams, idx=link['stg_idx'].values, attr='v', value=p_stg)
806
+ rtn.set(src=vname_ams, idx=link['stg_idx'].values, attr='v', value=p_dyg)
807
+
808
+ pname_to_update.append(vname_ams)
809
+
810
+ var_dest = ''
811
+ var_dest += 'SynGen.Pe' if sa.SynGen.n > 0 else ''
812
+ var_dest += ', DG.Pe' if sa.DG.n > 0 else ''
813
+ var_dest += ', RenGen.Pe' if sa.RenGen.n > 0 else ''
814
+ var_dest += ', StaicGen.p' if sa.RenGen.n+sa.SynGen.n+sa.DG.n < sa.StaticGen.n else ''
815
+ logger.info(f'Receive <{vname_ams}> from {var_dest}')
816
+ continue
817
+
818
+ # --- other scenarios ---
819
+ if _dest_check(mname=mname_ads, pname=pname_ads, idx=idx_ads, adsys=sa):
820
+ v_ads = mdl_ads.get(src=pname_ads, attr='v', idx=idx_ads)
821
+ rtn.set(src=vname_ams, idx=idx_ads, attr='v', value=v_ads)
822
+ pname_to_update.append(vname_ams)
823
+ logger.warning(f'Receive <{vname_ams}> from {mname_ads}.{pname_ads}')
824
+
825
+ # --- update routine parameters ---
826
+ if no_update and (len(pname_to_update) > 0):
827
+ logger.info(f'Please update <{rtn.class_name}> parameters: {pname_to_update}')
828
+ elif len(pname_to_update) > 0:
829
+ rtn.update(params=pname_to_update, build_mats=False)
830
+ return True
831
+
832
+
833
+ def _dest_check(mname, pname, idx, adsys):
834
+ """
835
+ Check if destination is valid.
836
+
837
+ Parameters
838
+ ----------
839
+ mname : str
840
+ Target ANDES model/group name.
841
+ pname : str
842
+ Target ANDES parameter name.
843
+ idx : list
844
+ Target idx.
845
+ adsys : ANDES.system.System
846
+ Target ANDES system.
847
+ """
848
+ # --- check model ---
849
+ if not hasattr(adsys, mname):
850
+ raise ValueError(f'Model error: ANDES system <{hex(adsys)}> has no <{mname}>')
851
+
852
+ # --- check param ---
853
+ mdl = getattr(adsys, mname)
854
+ _is_grp = mname in adsys.groups.keys()
855
+ # if it is a group, iterate through all models in the group
856
+ mdls_grp_name = list(adsys.groups[mname].models.keys()) if _is_grp else [mname]
857
+ n_no_mdl = 0
858
+ for mdl_name in mdls_grp_name:
859
+ mdl_to_check = getattr(adsys, mdl_name, None)
860
+ if mdl_to_check is not None and hasattr(mdl_to_check, pname):
861
+ break # found the param in any one of the models, break
862
+ n_no_mdl += 1
863
+ if n_no_mdl == len(mdls_grp_name):
864
+ raise ValueError(f'Param error: ANDES <{mdl.class_name}> has no <{pname}>')
865
+
866
+ # --- check idx ---
867
+ if _is_grp:
868
+ _ads_idx = [v for mdl in mdl.models.values() for v in mdl.idx.v]
869
+ else:
870
+ _ads_idx = mdl.idx.v
871
+ if not set(idx).issubset(set(_ads_idx)):
872
+ idx_gap = set(idx) - set(_ads_idx)
873
+ raise ValueError(f'Idx error: ANDES <{mdl.class_name}> has no idx: {idx_gap}')
874
+
875
+ return True
876
+
877
+
878
+ def build_group_table(adsys, grp_name, param_name, mdl_name=None):
879
+ """
880
+ Build the table for devices in a group in an ANDES System.
881
+
882
+ Parameters
883
+ ----------
884
+ adsys : andes.system.System
885
+ The ANDES system to build the table
886
+ grp_name : string
887
+ The ANDES group
888
+ param_name : list of string
889
+ The common columns of a group that to be included in the table.
890
+ mdl_name : list of string
891
+ The list of models that to be included in the table. Default as all models.
892
+
893
+ Returns
894
+ -------
895
+ DataFrame
896
+
897
+ The output Dataframe contains the columns from the device
898
+ """
899
+ grp_df = pd.DataFrame(columns=param_name)
900
+ grp = getattr(adsys, grp_name) # get the group instance
901
+
902
+ mdl_to_add = mdl_name if mdl_name else list(grp.models.keys())
903
+ mdl_dfs = [getattr(adsys, mdl).as_df()[param_name] for mdl in mdl_to_add]
904
+
905
+ grp_df = pd.concat(mdl_dfs, axis=0, ignore_index=True)
906
+
907
+ # --- type sanity check ---
908
+ mdl_1st = adsys.models[mdl_to_add[0]]
909
+ # NOTE: force IdxParam to be string type
910
+ cols_to_convert = [col for col in param_name if
911
+ (mdl_1st.params[col].class_name == 'IdxParam') and
912
+ (pd.api.types.is_numeric_dtype(grp_df[col]))]
913
+ # NOTE: if 'idx' is included, force it to be string type
914
+ if ('idx' in param_name) and pd.api.types.is_numeric_dtype(grp_df['idx']):
915
+ cols_to_convert.append('idx')
916
+
917
+ grp_df[cols_to_convert] = grp_df[cols_to_convert].astype(int).astype(str)
918
+ return grp_df
919
+
920
+
921
+ def make_link_table(adsys):
922
+ """
923
+ Build the link table for generators and generator controllers in an ANDES
924
+ System, including ``SynGen`` and ``DG`` for now.
925
+
926
+ Parameters
927
+ ----------
928
+ adsys : andes.system.System
929
+ The ANDES system to link
930
+
931
+ Returns
932
+ -------
933
+ DataFrame
934
+
935
+ Each column in the output Dataframe contains the ``idx`` of linked
936
+ ``StaticGen``, ``Bus``, ``DG``, ``RenGen``, ``RenExciter``, ``SynGen``,
937
+ ``Exciter``, and ``TurbineGov``, ``gammap``, ``gammaq``.
938
+ """
939
+ # --- build group tables ---
940
+ # 1) StaticGen
941
+ ssa_stg = build_group_table(adsys=adsys, grp_name='StaticGen',
942
+ param_name=['u', 'name', 'idx', 'bus'],
943
+ mdl_name=[])
944
+ # 2) TurbineGov
945
+ ssa_gov = build_group_table(adsys=adsys, grp_name='TurbineGov',
946
+ param_name=['idx', 'syn'],
947
+ mdl_name=[])
948
+ # 3) Exciter
949
+ ssa_exc = build_group_table(adsys=adsys, grp_name='Exciter',
950
+ param_name=['idx', 'syn'],
951
+ mdl_name=[])
952
+ # 4) SynGen
953
+ ssa_syg = build_group_table(adsys=adsys, grp_name='SynGen', mdl_name=['GENCLS', 'GENROU'],
954
+ param_name=['idx', 'bus', 'gen', 'gammap', 'gammaq'])
955
+ # 5) DG
956
+ ssa_dg = build_group_table(adsys=adsys, grp_name='DG', mdl_name=[],
957
+ param_name=['idx', 'bus', 'gen', 'gammap', 'gammaq'])
958
+ # 6) RenGen
959
+ ssa_rg = build_group_table(adsys=adsys, grp_name='RenGen', mdl_name=[],
960
+ param_name=['idx', 'bus', 'gen', 'gammap', 'gammaq'])
961
+ # 7) RenExciter
962
+ ssa_rexc = build_group_table(adsys=adsys, grp_name='RenExciter', mdl_name=[],
963
+ param_name=['idx', 'reg'])
964
+
965
+ # --- build link table ---
966
+ # NOTE: use bus index as unique identifier
967
+ ssa_bus = build_group_table(adsys=adsys, grp_name='ACTopology', mdl_name=['Bus'],
968
+ param_name=['name', 'idx'])
969
+ # 1) StaticGen
970
+ ssa_key = pd.merge(left=ssa_stg.rename(columns={'name': 'stg_name', 'idx': 'stg_idx',
971
+ 'bus': 'bus_idx', 'u': 'stg_u'}),
972
+ right=ssa_bus.rename(columns={'name': 'bus_name', 'idx': 'bus_idx'}),
973
+ how='left', on='bus_idx')
974
+ # 2) Dynamic Generators
975
+ ssa_syg = pd.merge(left=ssa_key, how='right', on='stg_idx',
976
+ right=ssa_syg.rename(columns={'idx': 'syg_idx', 'gen': 'stg_idx'}))
977
+ ssa_dg = pd.merge(left=ssa_key, how='right', on='stg_idx',
978
+ right=ssa_dg.rename(columns={'idx': 'dg_idx', 'gen': 'stg_idx'}))
979
+ ssa_rg = pd.merge(left=ssa_key, how='right', on='stg_idx',
980
+ right=ssa_rg.rename(columns={'idx': 'rg_idx', 'gen': 'stg_idx'}))
981
+
982
+ # NOTE: for StaticGen without Dynamic Generator, fill gammap and gammaq as 1
983
+ ssa_key0 = pd.merge(left=ssa_key, how='left', on='stg_idx',
984
+ right=ssa_syg[['stg_idx', 'syg_idx']])
985
+ ssa_key0 = pd.merge(left=ssa_key0, how='left', on='stg_idx',
986
+ right=ssa_dg[['stg_idx', 'dg_idx']])
987
+ ssa_key0 = pd.merge(left=ssa_key0, how='left', on='stg_idx',
988
+ right=ssa_rg[['stg_idx', 'rg_idx']])
989
+
990
+ # NOTE: use this instead of fillna to avoid type conversion
991
+ idxc = ['syg_idx', 'dg_idx', 'rg_idx']
992
+ ssa_key0[idxc] = ssa_key0[idxc].astype('str').replace({'nan': ''}).astype('bool')
993
+
994
+ dyr = ssa_key0['syg_idx'] + ssa_key0['dg_idx'] + ssa_key0['rg_idx']
995
+ non_dyr = np.logical_not(dyr)
996
+ ssa_dyr0 = ssa_key0[non_dyr].reset_index(drop=True)
997
+ ssa_dyr0['gammap'] = 1
998
+ ssa_dyr0['gammaq'] = 1
999
+
1000
+ ssa_key = pd.concat([ssa_syg, ssa_dg, ssa_rg, ssa_dyr0], axis=0)
1001
+ ssa_key = pd.merge(left=ssa_key,
1002
+ right=ssa_exc.rename(columns={'idx': 'exc_idx', 'syn': 'syg_idx'}),
1003
+ how='left', on='syg_idx')
1004
+ ssa_key = pd.merge(left=ssa_key,
1005
+ right=ssa_gov.rename(columns={'idx': 'gov_idx', 'syn': 'syg_idx'}),
1006
+ how='left', on='syg_idx')
1007
+ ssa_key = pd.merge(left=ssa_key, how='left', on='rg_idx',
1008
+ right=ssa_rexc.rename(columns={'idx': 'rexc_idx', 'reg': 'rg_idx'}))
1009
+
1010
+ # NOTE: other cols might be useful in the future
1011
+ # cols = ['stg_name', 'stg_u', 'stg_idx', 'bus_idx', 'dg_idx', 'rg_idx', 'rexc_idx',
1012
+ # 'syg_idx', 'exc_idx', 'gov_idx', 'bus_name', 'gammap', 'gammaq']
1013
+ # re-order columns
1014
+ cols = ['stg_idx', 'bus_idx', # static gen
1015
+ 'syg_idx', 'gov_idx', # syn gen
1016
+ 'dg_idx', # distributed gen
1017
+ 'rg_idx', # renewable gen
1018
+ 'gammap', 'gammaq', # gamma
1019
+ ]
1020
+ out = ssa_key[cols].sort_values(by='stg_idx', ascending=False).reset_index(drop=True)
1021
+ return out
1022
+
1023
+
1024
+ def verify_pf(amsys, adsys, tol=1e-3):
1025
+ """
1026
+ Verify the power flow results between AMS and ANDES.
1027
+ Note that this function will run PFlow in both systems.
1028
+
1029
+ Parameters
1030
+ ----------
1031
+ sp : ams.System
1032
+ The AMS system.
1033
+ sa : andes.System
1034
+ The ANDES system.
1035
+
1036
+ Returns
1037
+ -------
1038
+ bool
1039
+ True if the power flow results are consistent; False otherwise.
1040
+ """
1041
+ amsys.PFlow.run()
1042
+ if adsys.is_setup:
1043
+ adsys.PFlow.run()
1044
+ else:
1045
+ logger.info('ANDES system is not setup, quit verification.')
1046
+ return False
1047
+ v_check = np.allclose(amsys.Bus.v.v, adsys.Bus.v.v, atol=tol)
1048
+ a_check = np.allclose(amsys.Bus.a.v, adsys.Bus.a.v, atol=tol)
1049
+ check = v_check and a_check
1050
+
1051
+ v_diff_max = np.max(np.abs(amsys.Bus.v.v - adsys.Bus.v.v))
1052
+ a_diff_max = np.max(np.abs(amsys.Bus.a.v - adsys.Bus.a.v))
1053
+ diff_msg = f'Voltage diff max: {v_diff_max}, Angle diff max: {a_diff_max}'
1054
+ logger.debug(diff_msg)
1055
+ if check:
1056
+ logger.info('Power flow results are consistent.')
1057
+ else:
1058
+ msg = 'Power flow results are inconsistent!'
1059
+ logger.warning(msg)
1060
+ logger.warning(diff_msg)
1061
+ return check
1062
+
1063
+
1064
+ def replace_dev(row, mdl, dev, idx_map):
1065
+ """
1066
+ Replace the device idx in the row based on the idx_map.
1067
+
1068
+ Parameters
1069
+ ----------
1070
+ row : pd.Series
1071
+ The row of the DataFrame.
1072
+ mdl : str
1073
+ The column name for the Model.
1074
+ dev : str
1075
+ The column name for the Device idx.
1076
+ idx_map : dict
1077
+ The index map for replacement.
1078
+
1079
+ Returns
1080
+ -------
1081
+ str
1082
+ The new device idx.
1083
+ """
1084
+ old_idx = row[dev]
1085
+ return idx_map.get(row[mdl], {}).get(old_idx, old_idx)