├── PSCAD_DDPG.bakx ├── PSCAD_DDPG.if15 ├── LicenseConfig.cfg ├── Main.dta ├── Main.f ├── Main.obj ├── PSCAD_DDPG.30065.bat ├── PSCAD_DDPG.exe ├── PSCAD_DDPG.mak ├── PSCAD_DDPG.mak.bat ├── PSCAD_DDPG.map ├── Station.dta ├── Station.f ├── Station.obj ├── c_interface_python.obj └── fortran_interface_c_1.obj ├── PSCAD_DDPG.pscx ├── PSCAD_DDPG.psmx ├── README.md ├── __pycache__ ├── ddpg_main.cpython-37.pyc └── ddpg_main1.cpython-37.pyc ├── c_interface_python.c ├── ddpg_main.py ├── fortran_interface_c.f90 └── fortran_interface_c_1.f90 /PSCAD_DDPG.bakx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 |
94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 |
117 | 118 | true 119 | true 120 | true 121 | true 122 | true 123 | true 124 | true 125 | 126 | 127 | Freq 128 | 129 | 130 | 131 | Reward 132 | 133 | 134 | 135 | Done 136 | 137 | 138 | 139 | Simu_Step_In 140 | 141 | 142 | 143 | Act 144 | 145 | Simu_Step_Out 146 | 147 | 157 |
158 | 159 | 160 | 161 | 162 |
163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 |
186 | 187 | true 188 | true 189 | true 190 | true 191 | true 192 | 193 | 194 | Freq 195 | 196 | 197 | 198 | Simu_Step_In 199 | 200 | 201 | 202 | Act 203 | 204 | Simu_Step_Out 205 | 206 | 244 |
245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 |
277 | 278 | 279 | %:Name 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/LicenseConfig.cfg: -------------------------------------------------------------------------------- 1 | Version: 1 2 | Address = 10.0.0.17 3 | Port = 60498 4 | Key = b@5"BeKp.pAf(\?x]PUk(lW-(M|+]?lI+&zp9QzQA!:3&*&hIsRVa4J7s9w"6X)%LG$@ks)6GGPg:uGy1;M\/e|Bjm1,y!2*GFJ{hA,R)}Vn7"P*!^l/4`Z%|3||RDb\`xu-ETUI<=3`G$|N*6J?zb5zY9ai1k1`0M4Xnu'qH.{s>=.':M(lJ3tM)d=,W^OA!?|'GZn9bX7;$e#B~fIp8{LvaXkq~0I=!MXSY#P1}glx41TT 5 | -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/Main.dta: -------------------------------------------------------------------------------- 1 | !======================================================================= 2 | ! Generated by : PSCAD v4.6.3.0 3 | ! 4 | ! Warning: The content of this file is automatically generated. 5 | ! Do not modify, as any changes made here will be lost! 6 | !======================================================================= 7 | 8 | 9 | !--------------------------------------- 10 | ! Local Node Voltages 11 | !--------------------------------------- 12 | VOLTAGES: 13 | 14 | 15 | DATADSD: 16 | 17 | 18 | DATADSO: 19 | 20 | 21 | 22 | ENDPAGE 23 | -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/Main.f: -------------------------------------------------------------------------------- 1 | !======================================================================= 2 | ! Generated by : PSCAD v4.6.3.0 3 | ! 4 | ! Warning: The content of this file is automatically generated. 5 | ! Do not modify, as any changes made here will be lost! 6 | !----------------------------------------------------------------------- 7 | ! Component : Main 8 | ! Description : 9 | !----------------------------------------------------------------------- 10 | 11 | 12 | !======================================================================= 13 | 14 | SUBROUTINE MainDyn() 15 | 16 | !--------------------------------------- 17 | ! Standard includes 18 | !--------------------------------------- 19 | 20 | INCLUDE 'nd.h' 21 | INCLUDE 'emtconst.h' 22 | INCLUDE 'emtstor.h' 23 | INCLUDE 's0.h' 24 | INCLUDE 's1.h' 25 | INCLUDE 's2.h' 26 | INCLUDE 's4.h' 27 | INCLUDE 'branches.h' 28 | INCLUDE 'pscadv3.h' 29 | INCLUDE 'fnames.h' 30 | INCLUDE 'radiolinks.h' 31 | INCLUDE 'matlab.h' 32 | INCLUDE 'rtconfig.h' 33 | 34 | !--------------------------------------- 35 | ! Function/Subroutine Declarations 36 | !--------------------------------------- 37 | 38 | ! SUBR EMTDC_X2COMP ! 'Comparator with Interpolation' 39 | REAL REALPOLE ! Real Pole 40 | 41 | !--------------------------------------- 42 | ! Variable Declarations 43 | !--------------------------------------- 44 | 45 | 46 | ! Subroutine Arguments 47 | 48 | ! Electrical Node Indices 49 | 50 | ! Control Signals 51 | INTEGER IT_1, IT_2, Simulation_step 52 | REAL RT_1, RT_2, RT_3, RT_4, RT_5, RT_6 53 | REAL clk, RT_7, RT_8, RT_9, RT_10 54 | REAL RT_11, RT_12, RT_13 55 | 56 | ! Internal Variables 57 | REAL RVD2_1(2), state(2), action(2) 58 | 59 | ! Indexing variables 60 | INTEGER ICALL_NO ! Module call num 61 | INTEGER ISTOI, ISTOF, IT_0 ! Storage Indices 62 | INTEGER ICX, IPGB ! Control/Monitoring 63 | INTEGER SS ! SS/Node/Branch/Xfmr 64 | 65 | 66 | !--------------------------------------- 67 | ! Local Indices 68 | !--------------------------------------- 69 | 70 | ! Dsdyn <-> Dsout transfer index storage 71 | 72 | NTXFR = NTXFR + 1 73 | 74 | TXFR(NTXFR,1) = NSTOL 75 | TXFR(NTXFR,2) = NSTOI 76 | TXFR(NTXFR,3) = NSTOF 77 | TXFR(NTXFR,4) = NSTOC 78 | 79 | ! Define electric network subsystem number 80 | 81 | SS = NODE(NNODE+1) 82 | 83 | ! Increment and assign runtime configuration call indices 84 | 85 | ICALL_NO = NCALL_NO 86 | NCALL_NO = NCALL_NO + 1 87 | 88 | ! Increment global storage indices 89 | 90 | ISTOI = NSTOI 91 | NSTOI = NSTOI + 3 92 | ISTOF = NSTOF 93 | NSTOF = NSTOF + 14 94 | IPGB = NPGB 95 | NPGB = NPGB + 4 96 | ICX = NCX 97 | NCX = NCX + 1 98 | NNODE = NNODE + 2 99 | NCSCS = NCSCS + 0 100 | NCSCR = NCSCR + 0 101 | 102 | !--------------------------------------- 103 | ! Transfers from storage arrays 104 | !--------------------------------------- 105 | 106 | RT_1 = STOF(ISTOF + 1) 107 | RT_2 = STOF(ISTOF + 2) 108 | RT_3 = STOF(ISTOF + 3) 109 | RT_4 = STOF(ISTOF + 4) 110 | RT_5 = STOF(ISTOF + 5) 111 | IT_1 = STOI(ISTOI + 1) 112 | RT_6 = STOF(ISTOF + 6) 113 | IT_2 = STOI(ISTOI + 2) 114 | clk = STOF(ISTOF + 7) 115 | RT_7 = STOF(ISTOF + 8) 116 | RT_8 = STOF(ISTOF + 9) 117 | RT_9 = STOF(ISTOF + 10) 118 | Simulation_step = STOI(ISTOI + 3) 119 | RT_10 = STOF(ISTOF + 11) 120 | RT_11 = STOF(ISTOF + 12) 121 | RT_12 = STOF(ISTOF + 13) 122 | RT_13 = STOF(ISTOF + 14) 123 | 124 | 125 | !--------------------------------------- 126 | ! Electrical Node Lookup 127 | !--------------------------------------- 128 | 129 | 130 | !--------------------------------------- 131 | ! Configuration of Models 132 | !--------------------------------------- 133 | 134 | IF ( TIMEZERO ) THEN 135 | FILENAME = 'Main.dta' 136 | CALL EMTDC_OPENFILE 137 | SECTION = 'DATADSD:' 138 | CALL EMTDC_GOTOSECTION 139 | ENDIF 140 | !--------------------------------------- 141 | ! Generated code from module definition 142 | !--------------------------------------- 143 | 144 | 145 | ! 10:[impulse] Impulse Generator /w Interpolation 146 | CALL E_XIGEN1_EXE(RVD2_1) 147 | RT_6 = RVD2_1(1) 148 | ! 149 | 150 | ! 20:[consti] Integer Constant 151 | 152 | IT_2 = 0 153 | 154 | ! 30:[var_switch] Two State Switch 'MAT-ENAB' 155 | IT_1 = NINT(CX(CXMAP(ICX+1))) 156 | 157 | ! 40:[const] Real Constant 158 | 159 | RT_9 = 0.0 160 | 161 | ! 50:[const] Real Constant 162 | 163 | RT_12 = 30.0 164 | 165 | ! 60:[time-sig] Output of Simulation Time 166 | RT_11 = TIME 167 | 168 | ! 70:[compare] Single Input Level Comparator 169 | ! 170 | ! 171 | CALL EMTDC_X2COMP(0,0,0.25,RT_11,60.0,0.0,30.0,RVD2_1) 172 | RT_1 = RVD2_1(1) 173 | 174 | ! 80:[select] Two Input Selector 175 | IF (IT_1 .EQ. RTCI(NRTCI)) THEN 176 | clk = RT_6 177 | ELSE 178 | clk = REAL(IT_2) 179 | ENDIF 180 | NRTCI = NRTCI + 1 181 | ! 182 | 183 | ! 90:[gain] Gain Block 184 | ! Gain 185 | RT_7 = -10.0 * RT_8 186 | 187 | ! 100:[sumjct] Summing/Differencing Junctions 188 | RT_3 = + RT_1 - RT_2 189 | 190 | ! 110:[abs] Absolute Value 191 | ! 192 | RT_8 = ABS(RT_3) 193 | ! 194 | 195 | ! 120:[compar] Two Input Comparator 196 | ! 197 | CALL EMTDC_X2COMP(0,0,RT_8,RT_12,-100.0,0.0,0.0,RVD2_1) 198 | RT_13 = RVD2_1(1) 199 | 200 | ! 130:[sumjct] Summing/Differencing Junctions 201 | RT_10 = + RT_7 + RT_13 202 | 203 | ! 140:[RL_Agent_DDPG] 'ddpg_test' 204 | state(1) = RT_3 205 | action(1) = RT_4 206 | IF(clk.GT.0.9) THEN 207 | ! call fortran_interface_c(RT_3,RT_10,RT_9,Simulation_step,RT_4,Simulation_step) 208 | call fortran_interface_c_1(Simulation_step,Simulation_st& 209 | &ep) 210 | ENDIF 211 | 212 | ! 150:[realpole] Real Pole 213 | ! Real_Pole 214 | RT_5 = REALPOLE(0,1,0,5.0,0.1,RT_4,0.0,-1.0E20,1.0E20) 215 | 216 | ! 160:[realpole] Real Pole 217 | ! Real_Pole 218 | RT_2 = REALPOLE(0,1,0,6.0,0.01,RT_5,0.0,-1.0E20,1.0E20) 219 | 220 | ! 170:[pgb] Output Channel 'Reward' 221 | 222 | PGB(IPGB+1) = RT_10 223 | 224 | ! 180:[pgb] Output Channel 'Untitled' 225 | 226 | PGB(IPGB+2) = REAL(Simulation_step) 227 | 228 | ! 190:[pgb] Output Channel 'Out' 229 | 230 | PGB(IPGB+3) = RT_2 231 | 232 | ! 200:[pgb] Output Channel 'Act' 233 | 234 | PGB(IPGB+4) = RT_4 235 | 236 | !--------------------------------------- 237 | ! Feedbacks and transfers to storage 238 | !--------------------------------------- 239 | 240 | STOF(ISTOF + 1) = RT_1 241 | STOF(ISTOF + 2) = RT_2 242 | STOF(ISTOF + 3) = RT_3 243 | STOF(ISTOF + 4) = RT_4 244 | STOF(ISTOF + 5) = RT_5 245 | STOI(ISTOI + 1) = IT_1 246 | STOF(ISTOF + 6) = RT_6 247 | STOI(ISTOI + 2) = IT_2 248 | STOF(ISTOF + 7) = clk 249 | STOF(ISTOF + 8) = RT_7 250 | STOF(ISTOF + 9) = RT_8 251 | STOF(ISTOF + 10) = RT_9 252 | STOI(ISTOI + 3) = Simulation_step 253 | STOF(ISTOF + 11) = RT_10 254 | STOF(ISTOF + 12) = RT_11 255 | STOF(ISTOF + 13) = RT_12 256 | STOF(ISTOF + 14) = RT_13 257 | 258 | 259 | !--------------------------------------- 260 | ! Transfer to Exports 261 | !--------------------------------------- 262 | 263 | !--------------------------------------- 264 | ! Close Model Data read 265 | !--------------------------------------- 266 | 267 | IF ( TIMEZERO ) CALL EMTDC_CLOSEFILE 268 | RETURN 269 | END 270 | 271 | !======================================================================= 272 | 273 | SUBROUTINE MainOut() 274 | 275 | !--------------------------------------- 276 | ! Standard includes 277 | !--------------------------------------- 278 | 279 | INCLUDE 'nd.h' 280 | INCLUDE 'emtconst.h' 281 | INCLUDE 'emtstor.h' 282 | INCLUDE 's0.h' 283 | INCLUDE 's1.h' 284 | INCLUDE 's2.h' 285 | INCLUDE 's4.h' 286 | INCLUDE 'branches.h' 287 | INCLUDE 'pscadv3.h' 288 | INCLUDE 'fnames.h' 289 | INCLUDE 'radiolinks.h' 290 | INCLUDE 'matlab.h' 291 | INCLUDE 'rtconfig.h' 292 | 293 | !--------------------------------------- 294 | ! Function/Subroutine Declarations 295 | !--------------------------------------- 296 | 297 | 298 | !--------------------------------------- 299 | ! Variable Declarations 300 | !--------------------------------------- 301 | 302 | 303 | ! Electrical Node Indices 304 | 305 | ! Control Signals 306 | INTEGER IT_2 307 | REAL RT_9, RT_12 308 | 309 | ! Internal Variables 310 | 311 | ! Indexing variables 312 | INTEGER ICALL_NO ! Module call num 313 | INTEGER ISTOL, ISTOI, ISTOF, ISTOC ! Storage Indices 314 | INTEGER SS ! SS/Node/Branch/Xfmr 315 | 316 | 317 | !--------------------------------------- 318 | ! Local Indices 319 | !--------------------------------------- 320 | 321 | ! Dsdyn <-> Dsout transfer index storage 322 | 323 | NTXFR = NTXFR + 1 324 | 325 | ISTOL = TXFR(NTXFR,1) 326 | ISTOI = TXFR(NTXFR,2) 327 | ISTOF = TXFR(NTXFR,3) 328 | ISTOC = TXFR(NTXFR,4) 329 | 330 | ! Define electric network subsystem number 331 | 332 | SS = NODE(NNODE+1) 333 | 334 | ! Increment and assign runtime configuration call indices 335 | 336 | ICALL_NO = NCALL_NO 337 | NCALL_NO = NCALL_NO + 1 338 | 339 | ! Increment global storage indices 340 | 341 | NPGB = NPGB + 4 342 | NCX = NCX + 0 343 | NNODE = NNODE + 2 344 | NCSCS = NCSCS + 0 345 | NCSCR = NCSCR + 0 346 | 347 | !--------------------------------------- 348 | ! Transfers from storage arrays 349 | !--------------------------------------- 350 | 351 | IT_2 = STOI(ISTOI + 2) 352 | RT_9 = STOF(ISTOF + 10) 353 | RT_12 = STOF(ISTOF + 13) 354 | 355 | 356 | !--------------------------------------- 357 | ! Electrical Node Lookup 358 | !--------------------------------------- 359 | 360 | 361 | !--------------------------------------- 362 | ! Configuration of Models 363 | !--------------------------------------- 364 | 365 | IF ( TIMEZERO ) THEN 366 | FILENAME = 'Main.dta' 367 | CALL EMTDC_OPENFILE 368 | SECTION = 'DATADSO:' 369 | CALL EMTDC_GOTOSECTION 370 | ENDIF 371 | !--------------------------------------- 372 | ! Generated code from module definition 373 | !--------------------------------------- 374 | 375 | 376 | ! 20:[consti] Integer Constant 377 | 378 | IT_2 = 0 379 | 380 | ! 40:[const] Real Constant 381 | 382 | RT_9 = 0.0 383 | 384 | ! 50:[const] Real Constant 385 | 386 | RT_12 = 30.0 387 | 388 | !--------------------------------------- 389 | ! Feedbacks and transfers to storage 390 | !--------------------------------------- 391 | 392 | STOI(ISTOI + 2) = IT_2 393 | STOF(ISTOF + 10) = RT_9 394 | STOF(ISTOF + 13) = RT_12 395 | 396 | 397 | !--------------------------------------- 398 | ! Close Model Data read 399 | !--------------------------------------- 400 | 401 | IF ( TIMEZERO ) CALL EMTDC_CLOSEFILE 402 | RETURN 403 | END 404 | 405 | !======================================================================= 406 | 407 | SUBROUTINE MainDyn_Begin() 408 | 409 | !--------------------------------------- 410 | ! Standard includes 411 | !--------------------------------------- 412 | 413 | INCLUDE 'nd.h' 414 | INCLUDE 'emtconst.h' 415 | INCLUDE 's0.h' 416 | INCLUDE 's1.h' 417 | INCLUDE 's4.h' 418 | INCLUDE 'branches.h' 419 | INCLUDE 'pscadv3.h' 420 | INCLUDE 'radiolinks.h' 421 | INCLUDE 'rtconfig.h' 422 | 423 | !--------------------------------------- 424 | ! Function/Subroutine Declarations 425 | !--------------------------------------- 426 | 427 | 428 | !--------------------------------------- 429 | ! Variable Declarations 430 | !--------------------------------------- 431 | 432 | 433 | ! Subroutine Arguments 434 | 435 | ! Electrical Node Indices 436 | 437 | ! Control Signals 438 | INTEGER IT_2 439 | REAL RT_9, RT_12 440 | 441 | ! Internal Variables 442 | 443 | ! Indexing variables 444 | INTEGER ICALL_NO ! Module call num 445 | INTEGER ICX ! Control/Monitoring 446 | INTEGER SS ! SS/Node/Branch/Xfmr 447 | 448 | 449 | !--------------------------------------- 450 | ! Local Indices 451 | !--------------------------------------- 452 | 453 | 454 | ! Define electric network subsystem number 455 | 456 | SS = NODE(NNODE+1) 457 | 458 | ! Increment and assign runtime configuration call indices 459 | 460 | ICALL_NO = NCALL_NO 461 | NCALL_NO = NCALL_NO + 1 462 | 463 | ! Increment global storage indices 464 | 465 | ICX = NCX 466 | NCX = NCX + 1 467 | NNODE = NNODE + 2 468 | NCSCS = NCSCS + 0 469 | NCSCR = NCSCR + 0 470 | 471 | !--------------------------------------- 472 | ! Electrical Node Lookup 473 | !--------------------------------------- 474 | 475 | 476 | !--------------------------------------- 477 | ! Generated code from module definition 478 | !--------------------------------------- 479 | 480 | 481 | ! 10:[impulse] Impulse Generator /w Interpolation 482 | CALL COMPONENT_ID(ICALL_NO,610191493) 483 | CALL E_XIGEN1_CFG(0,0.0,1.0,1000.0) 484 | 485 | ! 20:[consti] Integer Constant 486 | IT_2 = 0 487 | 488 | ! 30:[var_switch] Two State Switch 'MAT-ENAB' 489 | 490 | ! 40:[const] Real Constant 491 | RT_9 = 0.0 492 | 493 | ! 50:[const] Real Constant 494 | RT_12 = 30.0 495 | 496 | ! 60:[time-sig] Output of Simulation Time 497 | 498 | ! 70:[compare] Single Input Level Comparator 499 | 500 | ! 80:[select] Two Input Selector 501 | RTCI(NRTCI) = 1 502 | NRTCI = NRTCI + 1 503 | 504 | ! 90:[gain] Gain Block 505 | 506 | ! 100:[sumjct] Summing/Differencing Junctions 507 | 508 | ! 110:[abs] Absolute Value 509 | 510 | ! 120:[compar] Two Input Comparator 511 | 512 | ! 130:[sumjct] Summing/Differencing Junctions 513 | 514 | ! 140:[RL_Agent_DDPG] 'ddpg_test' 515 | 516 | ! 150:[realpole] Real Pole 517 | 518 | ! 160:[realpole] Real Pole 519 | 520 | ! 170:[pgb] Output Channel 'Reward' 521 | 522 | ! 180:[pgb] Output Channel 'Untitled' 523 | 524 | ! 190:[pgb] Output Channel 'Out' 525 | 526 | ! 200:[pgb] Output Channel 'Act' 527 | 528 | RETURN 529 | END 530 | 531 | !======================================================================= 532 | 533 | SUBROUTINE MainOut_Begin() 534 | 535 | !--------------------------------------- 536 | ! Standard includes 537 | !--------------------------------------- 538 | 539 | INCLUDE 'nd.h' 540 | INCLUDE 'emtconst.h' 541 | INCLUDE 's0.h' 542 | INCLUDE 's1.h' 543 | INCLUDE 's4.h' 544 | INCLUDE 'branches.h' 545 | INCLUDE 'pscadv3.h' 546 | INCLUDE 'radiolinks.h' 547 | INCLUDE 'rtconfig.h' 548 | 549 | !--------------------------------------- 550 | ! Function/Subroutine Declarations 551 | !--------------------------------------- 552 | 553 | 554 | !--------------------------------------- 555 | ! Variable Declarations 556 | !--------------------------------------- 557 | 558 | 559 | ! Subroutine Arguments 560 | 561 | ! Electrical Node Indices 562 | 563 | ! Control Signals 564 | INTEGER IT_2 565 | REAL RT_9, RT_12 566 | 567 | ! Internal Variables 568 | 569 | ! Indexing variables 570 | INTEGER ICALL_NO ! Module call num 571 | INTEGER SS ! SS/Node/Branch/Xfmr 572 | 573 | 574 | !--------------------------------------- 575 | ! Local Indices 576 | !--------------------------------------- 577 | 578 | 579 | ! Define electric network subsystem number 580 | 581 | SS = NODE(NNODE+1) 582 | 583 | ! Increment and assign runtime configuration call indices 584 | 585 | ICALL_NO = NCALL_NO 586 | NCALL_NO = NCALL_NO + 1 587 | 588 | ! Increment global storage indices 589 | 590 | NCX = NCX + 0 591 | NNODE = NNODE + 2 592 | NCSCS = NCSCS + 0 593 | NCSCR = NCSCR + 0 594 | 595 | !--------------------------------------- 596 | ! Electrical Node Lookup 597 | !--------------------------------------- 598 | 599 | 600 | !--------------------------------------- 601 | ! Generated code from module definition 602 | !--------------------------------------- 603 | 604 | 605 | ! 20:[consti] Integer Constant 606 | IT_2 = 0 607 | 608 | ! 40:[const] Real Constant 609 | RT_9 = 0.0 610 | 611 | ! 50:[const] Real Constant 612 | RT_12 = 30.0 613 | 614 | RETURN 615 | END 616 | 617 | -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/Main.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigao-123/PSCAD_Fortran_C_Python-Multi-Program/ae33d3675610d5893186b380c738bbd4c9082db6/PSCAD_DDPG.if15/Main.obj -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/PSCAD_DDPG.30065.bat: -------------------------------------------------------------------------------- 1 | call "C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2020.2.254\windows\bin\ifortvars.bat" intel64 2 | pushd "D:\C_Practice\Pyhton_C\Python_Invoker\x64\Debug\PSCAD_DDPG.if15\" 3 | PSCAD_DDPG.exe -v4 10.0.0.17 30065 locale=english-us 4 | popd 5 | -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/PSCAD_DDPG.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigao-123/PSCAD_Fortran_C_Python-Multi-Program/ae33d3675610d5893186b380c738bbd4c9082db6/PSCAD_DDPG.if15/PSCAD_DDPG.exe -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/PSCAD_DDPG.mak: -------------------------------------------------------------------------------- 1 | 2 | #------------------------------------------------------------------------------ 3 | # Project 'PSCAD_DDPG' make using the 'Intel(R) Visual Fortran Compiler 19.1.2.254 (64-bit)' compiler. 4 | #------------------------------------------------------------------------------ 5 | 6 | #------------------------------------------------------------------------------ 7 | # All project 8 | #------------------------------------------------------------------------------ 9 | 10 | all: targets 11 | @echo !--Make: succeeded. 12 | 13 | 14 | 15 | #------------------------------------------------------------------------------ 16 | # Directories, Platform, and Version 17 | #------------------------------------------------------------------------------ 18 | 19 | Arch = windows 20 | EmtdcDir = C:\PROGRA~2\PSCAD46\emtdc\if15 21 | EmtdcInc = $(EmtdcDir)\inc 22 | EmtdcBin = $(EmtdcDir)\$(Arch) 23 | EmtdcMain = $(EmtdcBin)\main.obj 24 | EmtdcLib = $(EmtdcBin)\emtdc.lib 25 | 26 | 27 | #------------------------------------------------------------------------------ 28 | # Fortran Compiler 29 | #------------------------------------------------------------------------------ 30 | 31 | FC_Name = ifort.exe 32 | FC_Suffix = obj 33 | FC_Args = /nologo /c /free /real_size:64 /fpconstant /warn:declarations /iface:default /align:dcommons /fpe:0 34 | FC_Debug = /O1 35 | FC_Preprocess = 36 | FC_Preproswitch = 37 | FC_Warn = 38 | FC_Checks = 39 | FC_Includes = /include:"$(EmtdcInc)" /include:"$(EmtdcDir)" /include:"$(EmtdcBin)" 40 | FC_Compile = $(FC_Name) $(FC_Args) $(FC_Includes) $(FC_Debug) $(FC_Warn) $(FC_Checks) 41 | 42 | #------------------------------------------------------------------------------ 43 | # C Compiler 44 | #------------------------------------------------------------------------------ 45 | 46 | CC_Name = cl.exe 47 | CC_Suffix = obj 48 | CC_Args = /nologo /MT /W3 /EHsc /c 49 | CC_Debug = /O2 50 | CC_Includes = 51 | CC_Compile = $(CC_Name) $(CC_Args) $(CC_Includes) $(CC_Debug) 52 | 53 | #------------------------------------------------------------------------------ 54 | # Linker 55 | #------------------------------------------------------------------------------ 56 | 57 | Link_Name = link.exe 58 | Link_Debug = 59 | Link_Args = /out:$@ /nologo /nodefaultlib:libc.lib /nodefaultlib:libcmtd.lib /subsystem:console 60 | Link = $(Link_Name) $(Link_Args) $(Link_Debug) 61 | 62 | #------------------------------------------------------------------------------ 63 | # Build rules for generated files 64 | #------------------------------------------------------------------------------ 65 | 66 | 67 | .f.$(FC_Suffix): 68 | @echo !--Compile: $< 69 | $(FC_Compile) $< 70 | 71 | 72 | 73 | .c.$(CC_Suffix): 74 | @echo !--Compile: $< 75 | $(CC_Compile) $< 76 | 77 | 78 | 79 | #------------------------------------------------------------------------------ 80 | # Build rules for file references 81 | #------------------------------------------------------------------------------ 82 | 83 | 84 | user_source_1.$(FC_Suffix): D:\C_PRAC~1\Pyhton_C\PYTHON~1\x64\Debug\FORTRA~2.F90 85 | @echo !--Compile: "D:\C_Practice\Pyhton_C\Python_Invoker\x64\Debug\fortran_interface_c_1.f90" 86 | copy "D:\C_Practice\Pyhton_C\Python_Invoker\x64\Debug\fortran_interface_c_1.f90" . 87 | $(FC_Compile) "fortran_interface_c_1.f90" 88 | del "fortran_interface_c_1.f90" 89 | 90 | user_source_2.$(CC_Suffix): D:\C_PRAC~1\Pyhton_C\PYTHON~1\x64\Debug\C_INTE~1.C 91 | @echo !--Compile: "D:\C_Practice\Pyhton_C\Python_Invoker\x64\Debug\c_interface_python.c" 92 | copy "D:\C_Practice\Pyhton_C\Python_Invoker\x64\Debug\c_interface_python.c" . 93 | $(CC_Compile) "c_interface_python.c" 94 | del "c_interface_python.c" 95 | 96 | #------------------------------------------------------------------------------ 97 | # Dependencies 98 | #------------------------------------------------------------------------------ 99 | 100 | 101 | FC_Objects = \ 102 | Station.$(FC_Suffix) \ 103 | Main.$(FC_Suffix) \ 104 | user_source_1.$(FC_Suffix) 105 | 106 | FC_ObjectsLong = \ 107 | "Station.$(FC_Suffix)" \ 108 | "Main.$(FC_Suffix)" \ 109 | "fortran_interface_c_1.$(FC_Suffix)" 110 | 111 | CC_Objects = \ 112 | user_source_2.$(CC_Suffix) 113 | 114 | CC_ObjectsLong = \ 115 | "c_interface_python.$(CC_Suffix)" 116 | 117 | UserLibs = 118 | 119 | SysLibs = ws2_32.lib 120 | 121 | Binary = PSCAD_DDPG.exe 122 | 123 | $(Binary): $(FC_Objects) $(CC_Objects) $(UserLibs) 124 | @echo !--Link: $@ 125 | $(Link) "$(EmtdcMain)" $(FC_ObjectsLong) $(CC_ObjectsLong) $(UserLibs) "$(EmtdcLib)" $(SysLibs) 126 | 127 | targets: $(Binary) 128 | 129 | 130 | clean: 131 | -del EMTDC_V* 132 | -del *.obj 133 | -del *.o 134 | -del *.exe 135 | @echo !--Make clean: succeeded. 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/PSCAD_DDPG.mak.bat: -------------------------------------------------------------------------------- 1 | call "C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2020.2.254\windows\bin\ifortvars.bat" intel64 2 | pushd "D:\C_Practice\Pyhton_C\Python_Invoker\x64\Debug\PSCAD_DDPG.if15\" 3 | nmake -f PSCAD_DDPG.mak 4 | popd 5 | -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/PSCAD_DDPG.map: -------------------------------------------------------------------------------- 1 | !======================================================================= 2 | ! RunVersion = v4.6.3.0 3 | ! RunTime = Fri Nov 20 12:17:02 2020 4 | 5 | ! 6 | ! Warning: The content of this file is automatically generated. 7 | ! Do not modify, as any changes made here will be lost! 8 | !----------------------------------------------------------------------- 9 | 10 | 11 | !======================================================================= 12 | ! Dimensioning information 13 | !----------------------------------------------------------------------- 14 | DIMENSIONS: 15 | NPAGES = 2 / Modules 16 | SUBSYS = 0 / Subsystems 17 | NNODES = 4 / Node look-up dimension 18 | NODES = 0 / Maximum node dimension 19 | BRANCHES = 0 / Maximum branch dimension 20 | TRAFOS = 0 / Transformers 21 | WINDINGS = 0 / Max windings per xfrmr 22 | HARM_N = 0 / Total special harmonic devices 23 | VARS = 0 / Total 24 | PGBS = 4 / Output Channels 25 | STOR = 0 / Model Storage Legacy 26 | STORL = 0 / Model Storage Logical 27 | STORI = 5 / Model Storage Integer 28 | STORF = 16 / Model Storage Real 29 | STORC = 0 / Model Storage Complex 30 | STOL = 0 / Internal Storage Logical 31 | STOI = 3 / Internal Storage Integer 32 | STOF = 14 / Internal Storage Real 33 | STOC = 0 / Internal Storage Complex 34 | CX = 1 / Control transfers array size 35 | CXMAP = 1 / Control transfers map size 36 | TX = 0 / Transmit transfers array size 37 | TXRX = 0 / Transmit transfers map size 38 | RTCL = 0 / Runtime Configuration Logical 39 | RTCI = 1 / Runtime Configuration Integer 40 | RTCF = 4 / Runtime Configuration Real 41 | RTCC = 0 / Runtime Configuration Complex 42 | STXFRL = 0 / DSDYN<->DSOUT Transfer Logical 43 | STXFRI = 0 / DSDYN<->DSOUT Transfer Integer 44 | STXFRF = 0 / DSDYN<->DSOUT Transfer Real 45 | STXFRC = 0 / DSDYN<->DSOUT Transfer Complex 46 | CSCS = 0 / Control Signal Carrier Send Dim 47 | CSCR = 0 / Control Signal Carrier Recv Dim 48 | 49 | 50 | !======================================================================= 51 | ! Runtime Parameters 52 | !----------------------------------------------------------------------- 53 | PARAMETERS: 54 | TITLE = '' 55 | VERSION = 3.100 56 | START_TIME = 0.0 57 | FINISH_TIME = 0.5 58 | TIME_STEP = 5.0e-05 59 | PRINT_STEP = 5.0e-05 60 | CHATTER_LEVEL = .001 61 | SHORT_CIRCUIT = 0.0005 62 | DETECT_CHATTER = 'YES' 63 | REMOVE_CHATTER = 'YES' 64 | INTERPOLATE = 'YES' 65 | EXTRAPOLATE = 'YES' 66 | ECHO_DATA = 'NO' 67 | PRINT_DIMENSIONS = 'NO' 68 | USE_SUBSYSDIM = 'YES' 69 | 70 | 71 | !======================================================================= 72 | ! Sub-system and node mapping 73 | !----------------------------------------------------------------------- 74 | 75 | SUBSYSDIM: 76 | 0 77 | 78 | SUBS: 79 | 1 1 80 | 81 | MAP: "Station.dta" ! 82 | 0 0 / 83 | 0 0 84 | 85 | MAP: "Main.dta" ! 86 | 0 0 / 87 | 0 0 88 | 89 | 90 | !======================================================================= 91 | ! Controls Mapping 92 | !----------------------------------------------------------------------- 93 | CX: 94 | 1 1.0 / Main.var_switch 'MAT-ENAB' 95 | 96 | CXMAP: 97 | 1 1 / Main:0 98 | 99 | !======================================================================= 100 | ! Recorder Channel Information 101 | !----------------------------------------------------------------------- 102 | PGBList: 103 | PGB(1) Output Desc="Reward" Group="Main" Max=2.0 Min=-2.0 Units="" 104 | PGB(2) Output Desc="Untitled" Group="Main" Max=2.0 Min=-2.0 Units="" 105 | PGB(3) Output Desc="Out" Group="Main" Max=2.0 Min=-2.0 Units="" 106 | PGB(4) Output Desc="Act" Group="Main" Max=2.0 Min=-2.0 Units="" 107 | 108 | 109 | ENDCASE: 110 | -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/Station.dta: -------------------------------------------------------------------------------- 1 | !======================================================================= 2 | ! Generated by : PSCAD v4.6.3.0 3 | ! 4 | ! Warning: The content of this file is automatically generated. 5 | ! Do not modify, as any changes made here will be lost! 6 | !======================================================================= 7 | 8 | 9 | !--------------------------------------- 10 | ! Local Node Voltages 11 | !--------------------------------------- 12 | VOLTAGES: 13 | 14 | 15 | DATADSD: 16 | 17 | 18 | DATADSO: 19 | 20 | 21 | 22 | ENDPAGE 23 | -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/Station.f: -------------------------------------------------------------------------------- 1 | !======================================================================= 2 | ! Generated by : PSCAD v4.6.3.0 3 | ! 4 | ! Warning: The content of this file is automatically generated. 5 | ! Do not modify, as any changes made here will be lost! 6 | !----------------------------------------------------------------------- 7 | ! Component : Station 8 | ! Description : 9 | !----------------------------------------------------------------------- 10 | 11 | 12 | !======================================================================= 13 | 14 | SUBROUTINE DSDyn() 15 | 16 | !--------------------------------------- 17 | ! Standard includes 18 | !--------------------------------------- 19 | 20 | INCLUDE 'nd.h' 21 | INCLUDE 'emtconst.h' 22 | INCLUDE 'emtstor.h' 23 | INCLUDE 's0.h' 24 | INCLUDE 's1.h' 25 | INCLUDE 's2.h' 26 | INCLUDE 's4.h' 27 | INCLUDE 'branches.h' 28 | INCLUDE 'pscadv3.h' 29 | INCLUDE 'fnames.h' 30 | INCLUDE 'radiolinks.h' 31 | INCLUDE 'matlab.h' 32 | INCLUDE 'rtconfig.h' 33 | 34 | !--------------------------------------- 35 | ! Function/Subroutine Declarations 36 | !--------------------------------------- 37 | 38 | ! SUBR MainDyn ! 39 | 40 | !--------------------------------------- 41 | ! Variable Declarations 42 | !--------------------------------------- 43 | 44 | 45 | ! Subroutine Arguments 46 | 47 | ! Electrical Node Indices 48 | 49 | ! Control Signals 50 | 51 | ! Internal Variables 52 | 53 | ! Indexing variables 54 | INTEGER ICALL_NO ! Module call num 55 | INTEGER SS ! SS/Node/Branch/Xfmr 56 | 57 | 58 | !--------------------------------------- 59 | ! Local Indices 60 | !--------------------------------------- 61 | 62 | ! Dsdyn <-> Dsout transfer index storage 63 | 64 | NTXFR = NTXFR + 1 65 | 66 | TXFR(NTXFR,1) = NSTOL 67 | TXFR(NTXFR,2) = NSTOI 68 | TXFR(NTXFR,3) = NSTOF 69 | TXFR(NTXFR,4) = NSTOC 70 | 71 | ! Define electric network subsystem number 72 | 73 | SS = NODE(NNODE+1) 74 | 75 | ! Increment and assign runtime configuration call indices 76 | 77 | ICALL_NO = NCALL_NO 78 | NCALL_NO = NCALL_NO + 1 79 | 80 | ! Increment global storage indices 81 | 82 | NNODE = NNODE + 2 83 | NCSCS = NCSCS + 0 84 | NCSCR = NCSCR + 0 85 | 86 | !--------------------------------------- 87 | ! Transfers from storage arrays 88 | !--------------------------------------- 89 | 90 | 91 | 92 | !--------------------------------------- 93 | ! Electrical Node Lookup 94 | !--------------------------------------- 95 | 96 | 97 | !--------------------------------------- 98 | ! Configuration of Models 99 | !--------------------------------------- 100 | 101 | IF ( TIMEZERO ) THEN 102 | FILENAME = 'Station.dta' 103 | CALL EMTDC_OPENFILE 104 | SECTION = 'DATADSD:' 105 | CALL EMTDC_GOTOSECTION 106 | ENDIF 107 | !--------------------------------------- 108 | ! Generated code from module definition 109 | !--------------------------------------- 110 | 111 | 112 | ! -1:[Main] 113 | CALL MainDyn() 114 | 115 | 116 | !--------------------------------------- 117 | ! Feedbacks and transfers to storage 118 | !--------------------------------------- 119 | 120 | 121 | 122 | !--------------------------------------- 123 | ! Transfer to Exports 124 | !--------------------------------------- 125 | 126 | !--------------------------------------- 127 | ! Close Model Data read 128 | !--------------------------------------- 129 | 130 | IF ( TIMEZERO ) CALL EMTDC_CLOSEFILE 131 | RETURN 132 | END 133 | 134 | !======================================================================= 135 | 136 | SUBROUTINE DSOut() 137 | 138 | !--------------------------------------- 139 | ! Standard includes 140 | !--------------------------------------- 141 | 142 | INCLUDE 'nd.h' 143 | INCLUDE 'emtconst.h' 144 | INCLUDE 'emtstor.h' 145 | INCLUDE 's0.h' 146 | INCLUDE 's1.h' 147 | INCLUDE 's2.h' 148 | INCLUDE 's4.h' 149 | INCLUDE 'branches.h' 150 | INCLUDE 'pscadv3.h' 151 | INCLUDE 'fnames.h' 152 | INCLUDE 'radiolinks.h' 153 | INCLUDE 'matlab.h' 154 | INCLUDE 'rtconfig.h' 155 | 156 | !--------------------------------------- 157 | ! Function/Subroutine Declarations 158 | !--------------------------------------- 159 | 160 | ! SUBR MainOut ! 161 | 162 | !--------------------------------------- 163 | ! Variable Declarations 164 | !--------------------------------------- 165 | 166 | 167 | ! Electrical Node Indices 168 | 169 | ! Control Signals 170 | 171 | ! Internal Variables 172 | 173 | ! Indexing variables 174 | INTEGER ICALL_NO ! Module call num 175 | INTEGER ISTOL, ISTOI, ISTOF, ISTOC ! Storage Indices 176 | INTEGER SS ! SS/Node/Branch/Xfmr 177 | 178 | 179 | !--------------------------------------- 180 | ! Local Indices 181 | !--------------------------------------- 182 | 183 | ! Dsdyn <-> Dsout transfer index storage 184 | 185 | NTXFR = NTXFR + 1 186 | 187 | ISTOL = TXFR(NTXFR,1) 188 | ISTOI = TXFR(NTXFR,2) 189 | ISTOF = TXFR(NTXFR,3) 190 | ISTOC = TXFR(NTXFR,4) 191 | 192 | ! Define electric network subsystem number 193 | 194 | SS = NODE(NNODE+1) 195 | 196 | ! Increment and assign runtime configuration call indices 197 | 198 | ICALL_NO = NCALL_NO 199 | NCALL_NO = NCALL_NO + 1 200 | 201 | ! Increment global storage indices 202 | 203 | NNODE = NNODE + 2 204 | NCSCS = NCSCS + 0 205 | NCSCR = NCSCR + 0 206 | 207 | !--------------------------------------- 208 | ! Transfers from storage arrays 209 | !--------------------------------------- 210 | 211 | 212 | 213 | !--------------------------------------- 214 | ! Electrical Node Lookup 215 | !--------------------------------------- 216 | 217 | 218 | !--------------------------------------- 219 | ! Configuration of Models 220 | !--------------------------------------- 221 | 222 | IF ( TIMEZERO ) THEN 223 | FILENAME = 'Station.dta' 224 | CALL EMTDC_OPENFILE 225 | SECTION = 'DATADSO:' 226 | CALL EMTDC_GOTOSECTION 227 | ENDIF 228 | !--------------------------------------- 229 | ! Generated code from module definition 230 | !--------------------------------------- 231 | 232 | 233 | ! -1:[Main] 234 | CALL MainOut() 235 | 236 | 237 | !--------------------------------------- 238 | ! Feedbacks and transfers to storage 239 | !--------------------------------------- 240 | 241 | 242 | 243 | !--------------------------------------- 244 | ! Close Model Data read 245 | !--------------------------------------- 246 | 247 | IF ( TIMEZERO ) CALL EMTDC_CLOSEFILE 248 | RETURN 249 | END 250 | 251 | !======================================================================= 252 | 253 | SUBROUTINE DSDyn_Begin() 254 | 255 | !--------------------------------------- 256 | ! Standard includes 257 | !--------------------------------------- 258 | 259 | INCLUDE 'nd.h' 260 | INCLUDE 'emtconst.h' 261 | INCLUDE 's0.h' 262 | INCLUDE 's1.h' 263 | INCLUDE 's4.h' 264 | INCLUDE 'branches.h' 265 | INCLUDE 'pscadv3.h' 266 | INCLUDE 'radiolinks.h' 267 | INCLUDE 'rtconfig.h' 268 | 269 | !--------------------------------------- 270 | ! Function/Subroutine Declarations 271 | !--------------------------------------- 272 | 273 | ! SUBR MainDyn_Begin ! 274 | 275 | !--------------------------------------- 276 | ! Variable Declarations 277 | !--------------------------------------- 278 | 279 | 280 | ! Subroutine Arguments 281 | 282 | ! Electrical Node Indices 283 | 284 | ! Control Signals 285 | 286 | ! Internal Variables 287 | 288 | ! Indexing variables 289 | INTEGER ICALL_NO ! Module call num 290 | INTEGER SS ! SS/Node/Branch/Xfmr 291 | 292 | 293 | !--------------------------------------- 294 | ! Local Indices 295 | !--------------------------------------- 296 | 297 | 298 | ! Define electric network subsystem number 299 | 300 | SS = NODE(NNODE+1) 301 | 302 | ! Increment and assign runtime configuration call indices 303 | 304 | ICALL_NO = NCALL_NO 305 | NCALL_NO = NCALL_NO + 1 306 | 307 | ! Increment global storage indices 308 | 309 | NNODE = NNODE + 2 310 | NCSCS = NCSCS + 0 311 | NCSCR = NCSCR + 0 312 | 313 | !--------------------------------------- 314 | ! Electrical Node Lookup 315 | !--------------------------------------- 316 | 317 | 318 | !--------------------------------------- 319 | ! Generated code from module definition 320 | !--------------------------------------- 321 | 322 | 323 | ! -1:[Main] 324 | CALL MainDyn_Begin() 325 | 326 | 327 | RETURN 328 | END 329 | 330 | !======================================================================= 331 | 332 | SUBROUTINE DSOut_Begin() 333 | 334 | !--------------------------------------- 335 | ! Standard includes 336 | !--------------------------------------- 337 | 338 | INCLUDE 'nd.h' 339 | INCLUDE 'emtconst.h' 340 | INCLUDE 's0.h' 341 | INCLUDE 's1.h' 342 | INCLUDE 's4.h' 343 | INCLUDE 'branches.h' 344 | INCLUDE 'pscadv3.h' 345 | INCLUDE 'radiolinks.h' 346 | INCLUDE 'rtconfig.h' 347 | 348 | !--------------------------------------- 349 | ! Function/Subroutine Declarations 350 | !--------------------------------------- 351 | 352 | ! SUBR MainOut_Begin ! 353 | 354 | !--------------------------------------- 355 | ! Variable Declarations 356 | !--------------------------------------- 357 | 358 | 359 | ! Subroutine Arguments 360 | 361 | ! Electrical Node Indices 362 | 363 | ! Control Signals 364 | 365 | ! Internal Variables 366 | 367 | ! Indexing variables 368 | INTEGER ICALL_NO ! Module call num 369 | INTEGER SS ! SS/Node/Branch/Xfmr 370 | 371 | 372 | !--------------------------------------- 373 | ! Local Indices 374 | !--------------------------------------- 375 | 376 | 377 | ! Define electric network subsystem number 378 | 379 | SS = NODE(NNODE+1) 380 | 381 | ! Increment and assign runtime configuration call indices 382 | 383 | ICALL_NO = NCALL_NO 384 | NCALL_NO = NCALL_NO + 1 385 | 386 | ! Increment global storage indices 387 | 388 | NNODE = NNODE + 2 389 | NCSCS = NCSCS + 0 390 | NCSCR = NCSCR + 0 391 | 392 | !--------------------------------------- 393 | ! Electrical Node Lookup 394 | !--------------------------------------- 395 | 396 | 397 | !--------------------------------------- 398 | ! Generated code from module definition 399 | !--------------------------------------- 400 | 401 | 402 | ! -1:[Main] 403 | CALL MainOut_Begin() 404 | 405 | 406 | RETURN 407 | END 408 | 409 | -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/Station.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigao-123/PSCAD_Fortran_C_Python-Multi-Program/ae33d3675610d5893186b380c738bbd4c9082db6/PSCAD_DDPG.if15/Station.obj -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/c_interface_python.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigao-123/PSCAD_Fortran_C_Python-Multi-Program/ae33d3675610d5893186b380c738bbd4c9082db6/PSCAD_DDPG.if15/c_interface_python.obj -------------------------------------------------------------------------------- /PSCAD_DDPG.if15/fortran_interface_c_1.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigao-123/PSCAD_Fortran_C_Python-Multi-Program/ae33d3675610d5893186b380c738bbd4c9082db6/PSCAD_DDPG.if15/fortran_interface_c_1.obj -------------------------------------------------------------------------------- /PSCAD_DDPG.pscx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | true 119 | true 120 | true 121 | true 122 | true 123 | true 124 | true 125 | 126 | 127 | Freq 128 | 129 | 130 | 131 | Reward 132 | 133 | 134 | 135 | Done 136 | 137 | 138 | 139 | Simu_Step_In 140 | 141 | 142 | 143 | Act 144 | 145 | Simu_Step_Out 146 | 147 | 157 | 158 | 159 | 160 | 161 | 162 |
163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 |
186 | 187 | true 188 | true 189 | true 190 | true 191 | true 192 | 193 | 194 | Freq 195 | 196 | 197 | 198 | Simu_Step_In 199 | 200 | 201 | 202 | Act 203 | 204 | Simu_Step_Out 205 | 206 | 244 |
245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 |
277 | 278 | 279 | %:Name 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | -------------------------------------------------------------------------------- /PSCAD_DDPG.psmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | call "C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2020.2.254\windows\bin\ifortvars.bat" intel64 ]]> 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PSCAD_Fortran_C_Python-Multi-Program 2 | A simple case for PSCAD-Python program via C and Fortran 3 | 4 | # Why this? 5 | A project of power system needs to be simulated in PSCAD, and it utilizes some advanced Refincement Learning algorithms to control the simulation. Since PSCAD does not provide a API that can some advanced languages like Python can directly use. 6 | 7 | # Basic structure 8 | PSCAD can create a self-defined component, in which a like-Fortran code can be written to call a Fortran-C interface function, and then the C funtion can call Python to use the RL algorithm written in Python. The key is how to transfer the data between those softwares. 9 | 10 | # Document introduction 11 | A typic second order system, refer to PSCAD_DDPG.pscx 12 | The Fortran-C-interface function, refer to fortran_interface_c_1.f90 13 | The C-Python-interface function, refer to c_interface_python.c 14 | The main RL algorithm, refer to ddpg_main.py 15 | 16 | # Environment setting 17 | The multiple programing is based on PSCAD 4.6.3, Intel Fortran compiler, VS 2019, Python 3.7 18 | 19 | Importrant thing 1: c_interface_python.c code needs some python include files and lib files (this include and lib folders are from Python root directory), since PSCAD will call VS 2019 via command line, we need to set the environment variables first, refer to: 20 | ## https://github.com/MicrosoftDocs/cpp-docs.zh-cn/blob/live/docs/build/setting-the-path-and-environment-variables-for-command-line-builds.md 21 | ## https://blog.csdn.net/m0_38125278/article/details/87191971?utm_medium=distribute.pc_relevant_bbs_down.none-task--2~all~first_rank_v2~rank_v28-3.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task--2~all~first_rank_v2~rank_v28-3.nonecase 22 | 23 | Importrant thing 2: When C is calling Python, it needs to use a embeded Python interpreter which requires some Pyhton dependencies: Lib, DLLs, python37.dll (those folders are from Python root directory and put them in the same directory as the PSCAD project) 24 | 25 | # Progress: 26 | Tested C can call Python can pass data back and forth without problem, but with PSCAD, it seems like there are something incompatible. 27 | 28 | (Put this aside) 29 | -------------------------------------------------------------------------------- /__pycache__/ddpg_main.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigao-123/PSCAD_Fortran_C_Python-Multi-Program/ae33d3675610d5893186b380c738bbd4c9082db6/__pycache__/ddpg_main.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/ddpg_main1.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigao-123/PSCAD_Fortran_C_Python-Multi-Program/ae33d3675610d5893186b380c738bbd4c9082db6/__pycache__/ddpg_main1.cpython-37.pyc -------------------------------------------------------------------------------- /c_interface_python.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weigao-123/PSCAD_Fortran_C_Python-Multi-Program/ae33d3675610d5893186b380c738bbd4c9082db6/c_interface_python.c -------------------------------------------------------------------------------- /ddpg_main.py: -------------------------------------------------------------------------------- 1 | ## 有bug,返回的数必须有变化,否则PSCAD会警告,导致输出始终为0 2 | ##Main code will only run one time 3 | 4 | # 5 | # num_states = 1 6 | # num_actions = 1 7 | # 8 | # upper_bound = 5 9 | # lower_bound = -5 10 | # 11 | # 12 | # ## Define noise class for action output 13 | class OUActionNoise: 14 | def __init__(self, mean, std_deviation, theta=0.15, dt=1e-2, x_initial=None): 15 | self.theta = theta 16 | self.mean = mean 17 | self.std_dev = std_deviation 18 | self.dt = dt 19 | self.x_initial = x_initial 20 | self.reset() 21 | 22 | def __call__(self): 23 | # Formula taken from https://www.wikipedia.org/wiki/Ornstein-Uhlenbeck_process. 24 | x = ( 25 | self.x_prev 26 | + self.theta * (self.mean - self.x_prev) * self.dt 27 | + self.std_dev * np.sqrt(self.dt) * np.random.normal(size=self.mean.shape) 28 | ) 29 | # Store x into x_prev 30 | # Makes next noise dependent on current one 31 | self.x_prev = x 32 | return x 33 | 34 | def reset(self): 35 | if self.x_initial is not None: 36 | self.x_prev = self.x_initial 37 | else: 38 | self.x_prev = np.zeros_like(self.mean) 39 | 40 | 41 | ## Define Buffer class 42 | class Buffer: 43 | def __init__(self, buffer_capacity=100000, batch_size=64): 44 | # Number of "experiences" to store at max 45 | self.buffer_capacity = buffer_capacity 46 | # Num of tuples to train on. 47 | self.batch_size = batch_size 48 | 49 | # Its tells us num of times record() was called. 50 | self.buffer_counter = 0 51 | 52 | # Instead of list of tuples as the exp.replay concept go 53 | # We use different np.arrays for each tuple element 54 | self.state_buffer = np.zeros((self.buffer_capacity, num_states)) 55 | self.action_buffer = np.zeros((self.buffer_capacity, num_actions)) 56 | self.reward_buffer = np.zeros((self.buffer_capacity, 1)) 57 | self.next_state_buffer = np.zeros((self.buffer_capacity, num_states)) 58 | 59 | # Takes (s,a,r,s') obervation tuple as input 60 | def record(self, obs_tuple): 61 | # Set index to zero if buffer_capacity is exceeded, 62 | # replacing old records 63 | index = self.buffer_counter % self.buffer_capacity 64 | 65 | self.state_buffer[index] = obs_tuple[0] 66 | self.action_buffer[index] = obs_tuple[1] 67 | self.reward_buffer[index] = obs_tuple[2] 68 | self.next_state_buffer[index] = obs_tuple[3] 69 | 70 | self.buffer_counter = self.buffer_counter + 1 71 | 72 | # Eager execution is turned on by default in TensorFlow 2. Decorating with tf.function allows 73 | # TensorFlow to build a static graph out of the logic and computations in our function. 74 | # This provides a large speed up for blocks of code that contain many small TensorFlow operations such as this one. 75 | # @tf.function 76 | def update( 77 | self, state_batch, action_batch, reward_batch, next_state_batch 78 | ): 79 | # Training and updating Actor & Critic networks. 80 | # See Pseudo Code. 81 | with tf.GradientTape() as tape: 82 | target_actions = target_actor(next_state_batch, training=True) 83 | y = reward_batch + gamma * target_critic( 84 | [next_state_batch, target_actions], training=True 85 | ) 86 | critic_value = critic_model([state_batch, action_batch], training=True) 87 | critic_loss = tf.math.reduce_mean(tf.math.square(y - critic_value)) 88 | 89 | critic_grad = tape.gradient(critic_loss, critic_model.trainable_variables) 90 | critic_optimizer.apply_gradients( 91 | zip(critic_grad, critic_model.trainable_variables) 92 | ) 93 | 94 | with tf.GradientTape() as tape: 95 | actions = actor_model(state_batch, training=True) 96 | critic_value = critic_model([state_batch, actions], training=True) 97 | # Used `-value` as we want to maximize the value given 98 | # by the critic for our actions 99 | actor_loss = -tf.math.reduce_mean(critic_value) 100 | 101 | actor_grad = tape.gradient(actor_loss, actor_model.trainable_variables) 102 | actor_optimizer.apply_gradients( 103 | zip(actor_grad, actor_model.trainable_variables) 104 | ) 105 | 106 | # We compute the loss and update parameters 107 | def learn(self): 108 | # Get sampling range 109 | record_range = min(self.buffer_counter, self.buffer_capacity) 110 | # Randomly sample indices 111 | batch_indices = np.random.choice(record_range, self.batch_size) 112 | 113 | # Convert to tensors 114 | state_batch = tf.convert_to_tensor(self.state_buffer[batch_indices]) 115 | action_batch = tf.convert_to_tensor(self.action_buffer[batch_indices]) 116 | reward_batch = tf.convert_to_tensor(self.reward_buffer[batch_indices]) 117 | reward_batch = tf.cast(reward_batch, dtype=tf.float32) 118 | next_state_batch = tf.convert_to_tensor(self.next_state_buffer[batch_indices]) 119 | 120 | self.update(state_batch, action_batch, reward_batch, next_state_batch) 121 | 122 | 123 | # @tf.function 124 | def update_target(target_weights, weights, tau): 125 | for (a, b) in zip(target_weights, weights): 126 | a.assign(b * tau + a * (1 - tau)) 127 | 128 | 129 | ## Define actor network function 130 | def get_actor(): 131 | # Initialize weights between -3e-3 and 3-e3 132 | last_init = tf.random_uniform_initializer(minval=-0.003, maxval=0.003) 133 | 134 | inputs = layers.Input(shape=(num_states,)) 135 | out = layers.Dense(256, activation="relu")(inputs) 136 | out = layers.Dense(256, activation="relu")(out) 137 | outputs = layers.Dense(1, activation="tanh", kernel_initializer=last_init)(out) 138 | 139 | # Our upper bound is 2.0 for Pendulum. 140 | outputs = outputs * upper_bound 141 | model = tf.keras.Model(inputs, outputs) 142 | return model 143 | 144 | 145 | ## Define critic network function 146 | def get_critic(): 147 | # State as input 148 | state_input = layers.Input(shape=(num_states)) 149 | state_out = layers.Dense(16, activation="relu")(state_input) 150 | state_out = layers.Dense(32, activation="relu")(state_out) 151 | 152 | # Action as input 153 | action_input = layers.Input(shape=(num_actions)) 154 | action_out = layers.Dense(32, activation="relu")(action_input) 155 | 156 | # Both are passed through seperate layer before concatenating 157 | concat = layers.Concatenate()([state_out, action_out]) 158 | 159 | out = layers.Dense(256, activation="relu")(concat) 160 | out = layers.Dense(256, activation="relu")(out) 161 | outputs = layers.Dense(1)(out) 162 | 163 | # Outputs single value for give state-action 164 | model = tf.keras.Model([state_input, action_input], outputs) 165 | return model 166 | 167 | 168 | ## Define policy function for taking action 169 | def policy(state, noise_object): 170 | sampled_actions = tf.squeeze(actor_model(state)) 171 | noise = noise_object() 172 | # Adding noise to action 173 | sampled_actions = sampled_actions.numpy() + noise 174 | 175 | # We make sure action is within bounds 176 | legal_action = np.clip(sampled_actions, lower_bound, upper_bound) 177 | 178 | return [np.squeeze(legal_action)] 179 | 180 | 181 | ## ddpg function for returning to MATLAB-PSCAD 182 | def ddpg(state_1, reward, Done, Simu_Step_In): 183 | import math 184 | import numpy as np 185 | import random 186 | import tensorflow as tf 187 | from tensorflow.keras import layers 188 | 189 | ## Environment setting 190 | num_states = 1 191 | num_actions = 1 192 | 193 | upper_bound = 5 194 | lower_bound = -5 195 | 196 | ## Training hyperparameters 197 | std_dev = 0.2 198 | ou_noise = OUActionNoise(mean=np.zeros(1), std_deviation=float(std_dev) * np.ones(1)) 199 | 200 | actor_model = get_actor() 201 | critic_model = get_critic() 202 | 203 | target_actor = get_actor() 204 | target_critic = get_critic() 205 | 206 | # Making the weights equal initially 207 | target_actor.set_weights(actor_model.get_weights()) 208 | target_critic.set_weights(critic_model.get_weights()) 209 | 210 | # Learning rate for actor-critic models 211 | critic_lr = 0.0002 212 | actor_lr = 0.0001 213 | 214 | critic_optimizer = tf.keras.optimizers.Adam(critic_lr) 215 | actor_optimizer = tf.keras.optimizers.Adam(actor_lr) 216 | 217 | # Discount factor for future rewards 218 | gamma = 0.9 219 | # Used to update target networks 220 | tau = 0.0005 221 | 222 | buffer = Buffer(50000, 64) 223 | 224 | episodic_reward = 0 225 | episodic_reward_store = [] 226 | ## Train or not Train 227 | Train = True 228 | 229 | ## Start Training 230 | if Train: 231 | if (Simu_Step_In == 0): 232 | ### Not the fist episode: Load the weights 233 | actor_model.load_weights("./PSCAD_actor/PSCAD_actor") 234 | critic_model.load_weights("./PSCAD_critic/PSCAD_critic") 235 | target_actor.load_weights("./PSCAD_target_actor/PSCAD_target_actor") 236 | target_critic.load_weights("./PSCAD_target_critic/PSCAD_target_critic") 237 | 238 | 239 | ### First episode: Save the weights 240 | actor_model.save_weights("./PSCAD_actor/PSCAD_actor") 241 | critic_model.save_weights("./PSCAD_critic/PSCAD_critic") 242 | target_actor.save_weights("./PSCAD_target_actor/PSCAD_target_actor") 243 | target_critic.save_weights("./PSCAD_target_critic/PSCAD_target_critic") 244 | # Save the experience buffer 245 | np.save('buffer_counter_store.npy', buffer.buffer_counter) 246 | np.save('state_buffer_store.npy', buffer.state_buffer) 247 | np.save('action_buffer_store.npy', buffer.action_buffer) 248 | np.save('reward_buffer_store.npy', buffer.reward_buffer) 249 | np.save('next_state_buffer_store.npy', buffer.next_state_buffer) 250 | # Save the episode reward for final plotting 251 | np.save('episodic_reward_store.npy', episodic_reward_store) 252 | 253 | 254 | 255 | 256 | ### First step in each episode: store the 'episodic_reward' and 'prev_state' 257 | np.save('episodic_reward.npy', episodic_reward) 258 | prev_state = np.array([state_1]) 259 | np.save('prev_state.npy', prev_state) 260 | tf_prev_state = tf.expand_dims(tf.convert_to_tensor(prev_state), 0) 261 | np.save('tf_prev_state.npy', tf_prev_state) 262 | 263 | # Execute action and save it 264 | sampled_actions = tf.squeeze(actor_model(tf_prev_state)) 265 | noise = ou_noise() 266 | # Adding noise to action 267 | sampled_actions = sampled_actions.numpy() + noise 268 | 269 | # We make sure action is within bounds 270 | legal_action = np.clip(sampled_actions, lower_bound, upper_bound) 271 | action = [np.squeeze(legal_action)] 272 | np.save('action.npy', action) 273 | # action = policy(tf_prev_state, ou_noise) ##卡在这一步,很奇怪,明明python运行没有问题(测试证明这是一个bug,我直接不用函数,直接写函数里面的code可以成功) 274 | # np.save('action.npy',action) 275 | 276 | action_1 = float(action[0]) 277 | Simu_Step_Out = Simu_Step_In + 1 278 | # 把当前的动作执行到PSCAD 279 | 280 | else: 281 | 282 | # Load previous state and previous action 283 | prev_state = np.load('prev_state.npy') 284 | action = np.load('action.npy') 285 | state = np.array([state_1]) 286 | 287 | # Load the weights 288 | actor_model.load_weights("./PSCAD_actor/PSCAD_actor") 289 | critic_model.load_weights("./PSCAD_critic/PSCAD_critic") 290 | 291 | target_actor.load_weights("./PSCAD_target_actor/PSCAD_target_actor") 292 | target_critic.load_weights("./PSCAD_target_critic/PSCAD_target_critic") 293 | 294 | buffer_counter_store = np.load('buffer_counter_store.npy') 295 | state_buffer_store = np.load('state_buffer_store.npy') 296 | action_buffer_store = np.load('action_buffer_store.npy') 297 | reward_buffer_store = np.load('reward_buffer_store.npy') 298 | next_state_buffer_store = np.load('next_state_buffer_store.npy') 299 | 300 | buffer.buffer_counter = int(buffer_counter_store) 301 | buffer.state_buffer = state_buffer_store 302 | buffer.action_buffer = action_buffer_store 303 | buffer.reward_buffer = reward_buffer_store 304 | buffer.next_state_buffer = next_state_buffer_store 305 | 306 | buffer.record((prev_state, action, reward, state)) 307 | 308 | episodic_reward = np.load('episodic_reward.npy') 309 | episodic_reward = float(episodic_reward) + reward ##此处也有一个bug,不能使用episodic_reward += Reward格式 310 | np.save('episodic_reward.npy', episodic_reward) 311 | 312 | # buffer.learn() ## 此处也有bug,所以把code从Buffer类中直接提取出来运行 313 | # Get sampling range 314 | record_range = min(buffer.buffer_counter, buffer.buffer_capacity) 315 | # Randomly sample indices 316 | batch_indices = np.random.choice(record_range, buffer.batch_size) 317 | 318 | # Convert to tensors 319 | state_batch = tf.convert_to_tensor(buffer.state_buffer[batch_indices]) 320 | action_batch = tf.convert_to_tensor(buffer.action_buffer[batch_indices]) 321 | reward_batch = tf.convert_to_tensor(buffer.reward_buffer[batch_indices]) 322 | reward_batch = tf.cast(reward_batch, dtype=tf.float32) 323 | next_state_batch = tf.convert_to_tensor(buffer.next_state_buffer[batch_indices]) 324 | 325 | # buffer.update(state_batch, action_batch, reward_batch, next_state_batch) ## 此处也有bug,所以把code从Buffer类中直接提取出来运行 326 | 327 | # Training and updating Actor & Critic networks. 328 | # See Pseudo Code. 329 | with tf.GradientTape() as tape: 330 | target_actions = target_actor(next_state_batch, training=True) 331 | y = reward_batch + gamma * target_critic([next_state_batch, target_actions], training=True) 332 | critic_value = critic_model([state_batch, action_batch], training=True) 333 | critic_loss = tf.math.reduce_mean(tf.math.square(y - critic_value)) 334 | 335 | critic_grad = tape.gradient(critic_loss, critic_model.trainable_variables) 336 | critic_optimizer.apply_gradients(zip(critic_grad, critic_model.trainable_variables)) 337 | 338 | with tf.GradientTape() as tape: 339 | actions = actor_model(state_batch, training=True) 340 | critic_value = critic_model([state_batch, actions], training=True) 341 | # Used '-value' as we want to maximize the value given 342 | # by the critic for our actions 343 | actor_loss = -tf.math.reduce_mean(critic_value) 344 | 345 | actor_grad = tape.gradient(actor_loss, actor_model.trainable_variables) 346 | actor_optimizer.apply_gradients(zip(actor_grad, actor_model.trainable_variables)) 347 | 348 | update_target(target_actor.variables, actor_model.variables, tau) 349 | update_target(target_critic.variables, critic_model.variables, tau) 350 | 351 | np.save('buffer_counter_store.npy', buffer.buffer_counter) 352 | np.save('state_buffer_store.npy', buffer.state_buffer) 353 | np.save('action_buffer_store.npy', buffer.action_buffer) 354 | np.save('reward_buffer_store.npy', buffer.reward_buffer) 355 | np.save('next_state_buffer_store.npy', buffer.next_state_buffer) 356 | 357 | # Save the weights 358 | actor_model.save_weights("./PSCAD_actor/PSCAD_actor") 359 | critic_model.save_weights("./PSCAD_critic/PSCAD_critic") 360 | 361 | target_actor.save_weights("./PSCAD_target_actor/PSCAD_target_actor") 362 | target_critic.save_weights("./PSCAD_target_critic/PSCAD_target_critic") 363 | 364 | tf_state = tf.expand_dims(tf.convert_to_tensor(state), 0) 365 | 366 | sampled_actions = tf.squeeze(actor_model(tf_state)) 367 | noise = ou_noise() 368 | # Adding noise to action 369 | sampled_actions = sampled_actions.numpy() + noise 370 | 371 | # We make sure action is within bounds 372 | legal_action = np.clip(sampled_actions, lower_bound, upper_bound) 373 | action = [np.squeeze(legal_action)] 374 | np.save('action.npy', action) 375 | 376 | prev_state = state 377 | np.save('prev_state.npy', prev_state) 378 | 379 | if (Simu_Step_In == 5000): 380 | episodic_reward_store = np.load('episodic_reward_store.npy') 381 | episodic_reward_store = np.append(episodic_reward_store, episodic_reward) 382 | np.save('episodic_reward_store.npy', episodic_reward_store) 383 | 384 | action_1 = float(action[0]) 385 | Simu_Step_Out = Simu_Step_In + 1 386 | 387 | ## Not train, just run 388 | else: 389 | 390 | # Load the weights 391 | actor_model.load_weights("./PSCAD_actor/PSCAD_actor") 392 | 393 | prev_state = np.array([state_1]) 394 | tf_prev_state = tf.expand_dims(tf.convert_to_tensor(prev_state), 0) 395 | 396 | sampled_actions = tf.squeeze(actor_model(tf_prev_state)) 397 | noise = ou_noise() 398 | # Adding noise to action 399 | sampled_actions = sampled_actions.numpy() + noise 400 | 401 | # sampled_actions = sampled_actions.numpy() 402 | 403 | # We make sure action is within bounds 404 | legal_action = np.clip(sampled_actions, lower_bound, upper_bound) 405 | action = [np.squeeze(legal_action)] 406 | # np.save('action.npy',action) 407 | # action = policy(tf_prev_state, ou_noise) ##卡在这一步,很奇怪,明明python运行没有问题(测试证明这是一个bug,我直接不用函数,直接写函数里面的code可以成功) 408 | # np.save('action.npy',action) 409 | 410 | action_1 = float(action[0]) 411 | Simu_Step_Out = Simu_Step_In + 1 412 | 413 | return action_1, Simu_Step_Out 414 | 415 | def add(a,b): 416 | import math 417 | import random 418 | import tensorflow as tf 419 | from tensorflow.keras import layers 420 | return a*b, a+b -------------------------------------------------------------------------------- /fortran_interface_c.f90: -------------------------------------------------------------------------------- 1 | subroutine fortran_interface_c(state_1,reward,Done,Simu_Step_In,action_1,Simu_Step_Out) 2 | implicit none 3 | real :: state_1, action_1 4 | real :: reward, Done 5 | integer :: Simu_Step_In, Simu_Step_Out 6 | 7 | ! Fortran 90 interface to a C procedure 8 | interface 9 | subroutine c_interface_python(state_1,reward,Done,Simu_Step_In,action_1,Simu_Step_Out) 10 | 11 | !DEC$ ATTRIBUTES C :: c_interface_python 12 | 13 | !DEC$ ATTRIBUTES REFERENCE :: state_1 14 | 15 | !DEC$ ATTRIBUTES REFERENCE :: reward 16 | 17 | !DEC$ ATTRIBUTES REFERENCE :: Done 18 | 19 | !DEC$ ATTRIBUTES REFERENCE :: Simu_Step_In 20 | 21 | !DEC$ ATTRIBUTES REFERENCE :: action_1 22 | 23 | !DEC$ ATTRIBUTES REFERENCE :: Simu_Step_Out 24 | 25 | ! 26 | 27 | ! in, out are passed by REFERENCE 28 | 29 | ! 30 | real :: state_1, action_1 31 | real :: reward, Done 32 | integer :: Simu_Step_In, Simu_Step_Out 33 | 34 | end subroutine c_interface_python 35 | end interface 36 | 37 | ! 38 | 39 | ! Call the C procedure 40 | 41 | ! 42 | 43 | call c_interface_python(state_1,reward,Done,Simu_Step_In,action_1,Simu_Step_Out) 44 | 45 | end subroutine fortran_interface_c 46 | 47 | 48 | -------------------------------------------------------------------------------- /fortran_interface_c_1.f90: -------------------------------------------------------------------------------- 1 | subroutine fortran_interface_c_1(Simu_Step_In,Simu_Step_Out) 2 | implicit none 3 | integer :: Simu_Step_In, Simu_Step_Out 4 | 5 | ! Fortran 90 interface to a C procedure 6 | interface 7 | subroutine c_interface_python(Simu_Step_In,Simu_Step_Out) 8 | 9 | !DEC$ ATTRIBUTES C :: c_interface_python 10 | 11 | !DEC$ ATTRIBUTES REFERENCE :: Simu_Step_In 12 | 13 | !DEC$ ATTRIBUTES REFERENCE :: Simu_Step_Out 14 | 15 | ! 16 | 17 | ! in, out are passed by REFERENCE 18 | 19 | ! 20 | 21 | integer :: Simu_Step_In, Simu_Step_Out 22 | 23 | end subroutine c_interface_python 24 | end interface 25 | 26 | ! 27 | 28 | ! Call the C procedure 29 | 30 | ! 31 | 32 | call c_interface_python(Simu_Step_In,Simu_Step_Out) 33 | 34 | end subroutine fortran_interface_c_1 35 | 36 | 37 | --------------------------------------------------------------------------------