似鸥电气 发表于 2020-5-10 13:31:39

PSCAD入门教程第7节:调用fortran编写的自定义函数(附模型)

第7节怎样在pscad中call自定义函数?(自定义函数由fortran语言编写)
http://static.video.qq.com/TPout.swf?vid=i0963fqf1i8&1314.swf
7.1pscad脚本中call的函数由fortran语言编写7.1.1 在Fortran编译器中编写如下函数(可以先在文本文档中写,再把文本档后缀改为.f,但前提是你装了fortran编译器):<!函数功能:比较i和j的大小,并将小赋值给i,大的赋值给j。注意每段前空6格>      
Subroutine my_bj(i,j)         
REAl i,j,t      
if (i>j) THEN      
t=i         
i=j         
j=t         
ENDIF         
end subroutine my_bj
7.1.2 将该函数文件加载到pscad中(讲解视频中可能忘说这步了...)。


7.1.3 新建一个自定义模型(元件),并在其中自定义模型中调用函数。

<!功能:通过调用两值比较函数,将三个输入i1、i2、i3从小到大排序,并按从小到大的顺序,依次赋值给o1、o2、o3输出>。
#STORAGE INTEGER:10
#STORAGE REAL:10
#LOCAL INTEGER NMY_NSTORF
#LOCAL INTEGER NMY_NSTORI
#LOCAL REAL a,b,c
#BEGIN
#ENDBEGIN      
a=$i1      
b=$i2      
c=$i3         
IF(a .gt.b) THEN         
call my_bj(a,b)         
ENDIF         
IF(b .gt.c) THEN         
call my_bj(b,c)         
ENDIF         
IF(a .gt.b) THEN         
call my_bj(a,b)         
ENDIF      
$o1=a      
$o2=b      
$o3=c
输出结果为:


7.1.4   对于多个子模块电容电压排序,需要注意的是,它不仅需要将多个子模块的电容电压值进行排序,还需要知道排序后的子模块电容的编号,这样才能确定是否让该子模块投切。
附一个我参考博客上的排序例子(该排序算法用于pscad中排序时,部分程序需要省略,但该程序借鉴意义极大):
<博主名称:楚香饭>链接如下:(http://bbs.fcode.cn/forum.php?mod=viewthread&tid=1350&highlight=)
! Recursive Fortran 95 quicksort routine! sorts real numbers into ascendingnumerical order! Author: Juli Rew, SCD Consultingjuliana@ucar.edu), 9/03! Based on algorithm from Cormen et al.,Introduction to Algorithms,! 1997 printing! Made F conformant by Walt Brainerdmodule qsort_c_module implicit none public :: QsortC private :: Partitioncontainsrecursivesubroutine QsortC(A,B)   real, intent(in out), dimension(:) :: A , B   integer :: iq   if(size(A) > 1) then   call Partition(A , B , iq)   call QsortC(A(:iq-1),B(:iq-1))   call QsortC(A(iq:),B(iq:))   endifendsubroutine QsortCsubroutine Partition(A , B , marker)   real, intent(in out), dimension(:) :: A , B   integer, intent(out) :: marker   integer :: i, j   real :: temp   real :: x      ! pivot point    x= A(1)   i= 0   j= size(A) + 1   do   j = j-1   do       if (A(j) <= x) exit       j = j-1   end do   i = i+1   do       if (A(i) >= x) exit       i = i+1   end do   if (i < j) then       ! exchange A(i) and A(j)       temp = A(i)       A(i) = A(j)       A(j) = temp       temp = B(i)       B(i) = B(j)       B(j) = temp   elseif (i == j) then       marker = i+1       return   else       marker = i       return   endif   end doendsubroutine Partitionend module qsort_c_moduleuseqsort_c_moduleImplicit NoneInteger :: I,K,J !//我瞎写的Real :: $CLK = 1.0 ,$IARM =0.1,HLD1,FLAG1,$UNUM,HLD!//我瞎写的Real Uk(20) , Ukk(40) , T1(20) , $Ts1(20) ,$Us1(20)!//我瞎写的Real M(20)!//我瞎写的Real M1!//我瞎写的Real N1!//我瞎写的 call RANDOM_NUMBER( $us1)!//我瞎写的#LOCAL INTEGER T1(20)#LOCAL REAL M(20)#LOCAL REAL M1#LOCAL REAL N1IF($CLK>0.9) THEN    #LOCAL REAL Uk(20)   DO I=1,20   Uk(I)=$Us1(I)   ENDDO    #LOCAL REAL Ukk(40)   DO K=1,20   Ukk(K)=K   Ukk(20+K)=Uk(K)   ENDDO    IF ($Iarm>0) THEN   Hld1=1.0   DO I=1,20       IF ($Ts1(I)==1) THEN         Ukk(20+I)=Ukk(20+I)*Hld1       ENDIF   ENDDO   call QsortC( Ukk(21:) , Ukk(1:20) )!//排序   DO I=1,20       T1(I)=0   ENDDO   DO I=1,$Unum       M(I)=Ukk(I)       T1(M(I))=1   ENDDO   ENDIF   IF ($Iarm<0) THEN   Hld=1.0   DO I=1,20       IF ($Ts1(I)==1) THEN         Ukk(20+I)=Ukk(20+I)*Hld       ENDIF   ENDDO   call QsortC( Ukk(21:) , Ukk(1:20) )!//排序   DO I=1,20       T1(I)=0   ENDDO   DO I=1,$Unum       M(I)=Ukk(21-I)       T1(M(I))=1   ENDDO   ENDIF   DO I=1,20   $Ts1(I)=T1(I)   ENDDO ENDIFEnd

近期预告
1.PSCAD/Matlab仿真模型解读


往期回顾



PSCAD入门教程(第6节):构建自定义元件(附讲解模型)
简单示例模型在文章底部自行提取!



PSCAD入门教程(第5节): 4种常用元件的使用(附讲解模型)
简单示例模型在文章底部自行提取!

由于本人水平有限,所述内容难免会有疏漏之处,有遗漏或阐述不当之处请各位同学、老师傅指正,公众号私信或QQ(3135975766)。







示例模型百度网盘链接(其中有一个为官方CInterface模型可用于学习):

链接1:

https://pan.baidu.com/s/1U0_Lj0YbMHa1H1M9_iD7yQ

提取码1:p4u7

链接2:

https://pan.baidu.com/s/1APFaBsBzniOspbx0-jy8kA

提取码2:4ynb

页: [1]
查看完整版本: PSCAD入门教程第7节:调用fortran编写的自定义函数(附模型)