package DiodeRsParallelRsRshJpv; use Exporter; @ISA = qw(Exporter); #公開したいサブルーチン @EXPORT = qw(); use strict; use File::Basename; use Sci::DiodeRs; use Sci qw($pi $kB $R $NA $c $e $e0 $u0 $me $mp $mn $h $hbar $torad $todeg); #============================================================ # 変数等取得、再定義関数 #============================================================ sub SetTemperature { my ($this, $T) = @_; $this->{T} = $T; $this->{ekT} = $e / ($kB * $T); $this->{DiodeRs}->SetTemperature($T); } #============================================================ # コンストラクタ、デストラクタ #============================================================ sub new { my ($module) = @_; my $this = {}; bless $this; $this->{DiodeRs} = new DiodeRs; $this->SetTemperature(300.0); return $this; } sub DESTROY { my $this = shift; } #============================================================ # 一般関数 #============================================================ sub CalSCFTotalIV { my ($this, $Vtarget, $J01, $n1, $Rs1, $J02, $n2, $Rs2, $Rs, $Rsh, $Jpv, $LSQMethod, $EPS, $nMaxIter, $iPrintLevel) = @_; $LSQMethod = "ModifiedNewton" if(!defined $LSQMethod); $EPS = 1.0e-4 if(!defined $EPS); $nMaxIter = 100 if(!defined $nMaxIter); $iPrintLevel = 0 if(!defined $iPrintLevel); if($Rs == 0.0) { my ($Vtotal, $Jtotal) = $this->CalTotalIV($Vtarget, $J01, $n1, $Rs1, $J02, $n2, $Rs2, $Rs, $Rsh, $Jpv); return ($Vtotal, $Jtotal); } my $Opt = new Optimize; my @Guess = ($Vtarget); my @OptId = ( 1); my @Scale = ( 0.1); my ($OptVars, $MinVal) = $Opt->Optimize($LSQMethod, \@Guess, \@OptId, \@Scale, $EPS, $nMaxIter, $iPrintLevel, sub { $this->MinimizationFuncIV($Vtarget, $J01, $n1, $Rs1, $J02, $n2, $Rs2, $Rs, $Rsh, $Jpv, @_); }, sub { }, sub { Optimize::BuildDifferentialMatrixes(@_); }, ); my ($Vdiode) = @$OptVars; if($MinVal > $EPS) { print "Error i Cal: Could not get convergence for V=$Vtarget (MinVal=$MinVal)\n"; # exit; } my ($Vtotal, $Jtotal) = $this->CalTotalIV($Vdiode, $J01, $n1, $Rs1, $J02, $n2, $Rs2, $Rs, $Rsh, $Jpv); return ($Vdiode, $Jtotal); } sub CalTotalIV { my ($this, $Vdiode, $J01, $n1, $Rs1, $J02, $n2, $Rs2, $Rs, $Rsh, $Jpv) = @_; my ($V1, $J1) = $this->CalSCFTotalIVdiode1($Vdiode, $J01, $n1, $Rs1); my ($V2, $J2) = $this->CalSCFTotalIVdiode1($Vdiode, $J02, $n2, $Rs2); my $Jtotal = $J1 + $J2 + $Vdiode / $Rsh - $Jpv; my $Vtotal = $Vdiode + $Rs * $Jtotal; return ($Vtotal, $Jtotal); } sub MinimizationFuncIV { my ($this, $Vtarget, $J01, $n1, $Rs1, $J02, $n2, $Rs2, $Rs, $Rsh, $Jpv, $pVars, $iPrintLevel) = @_; my $S = 0.0; my ($Vdiode) = @$pVars; my ($Vtotal, $Jtotal) = $this->CalTotalIV($Vdiode, $J01, $n1, $Rs1, $J02, $n2, $Rs2, $Rs, $Rsh, $Jpv); return ($Vtotal - $Vtarget)**2; } sub CalSCFTotalIVdiode1 { my ($this, $Vtarget, $J0, $n, $Rs) = @_; return $this->{DiodeRs}->CalSCFTotalIV($Vtarget, $J0, $n, $Rs); } 1;