Code covered by the BSD License  

Highlights from
Bond graph add-on block library BG V.2.1

image thumbnail
from Bond graph add-on block library BG V.2.1 by Gert-Helge Geitner
Block library enables the graphical programming of Bond Graphs using standard Simulink and editor.

[VA,A2]=BGV2_Init(BT,Par1,Par2,Par3,Par4)
function [VA,A2]=BGV2_Init(BT,Par1,Par2,Par3,Par4)
%Initialisierungsfunktionen fr Erweiterungsbibliothek Bondgraph
%BG V.2
%BT = BlockTyp                        Par1 = eingegebener ParameterWert // ZU
%                                     Par2 = skalar/vektoriell // AB // AW(I/C)
%A2 = Ausgang 2,z.B. PV0/W2/PX;       Par3 = Textstring von TypAuswahl
%                                     Par4 = Nicht-linear Umschaltung // AWS

FT00='Fatal error - False BT code detected!';
FT01='-Element';
FT02='Value: real scalar input necessary!';
FT03='Value: real symmetric matrix input necessary!';
FT05='Value: real vector input necessary!';
FT06='Optional common gain - ';
FT07='Inconsistence of GainMatrixDimension and element-sum of InputVectorDimension!';
FT08='Inconsistence of GainMatrixDimension and element-sum of InputMatrixDimension!';
FT09='Fatal error - Unexpected switch code!';
FT12='Initial value: real scalar input necessary!';
FT13='Initial value: real vector input necessary!';
FT14a='WARNING - No automatic correction of initial values unequally to zero --- ';
FT14b='this correcion by the gain matrix is necessary due to the sequence int/mul.';
FT14c='Reason: you used a non-diagonal gain matrix!';
FT15='Dimension mismatch of parameter matrix and initial value vector!';
FT16='Value: real symmetric / unsymmetric matrix input necessary!';

h=gcb;
switch BT
  case {10}                                            %Source/Destination Block
                         %Zur Vereinfachung wird "Source extern" hier nicht abgefragt
       [i,j]=size(Par1);                               %Par1=Wert
       if   findstr(Par2,'Scalar')                     %Par2=MU 
            if ~isscalar(Par1)||~isreal(Par1)||isstr(Par1) %skalar/reell/kein_String?
               errordlg([h 10 10 FT02],['S/D' FT01]); return; end
            if findstr(Par3,'Source'), K=10; else K=14; end %Par3=TY; Alt.:Destin.
            if findstr(Par3,'Flow'),   K=K+2;           end %Par3=TY; Alt: Effort
            VA=Par1;
       else                                   %Vektor/kein_Skalar/reell/kein_String?
            if ~isvector(Par1)||isscalar(Par1)||~isreal(Par1)||isstr(Par1)
               errordlg([h 10 10 FT05],['S/D' FT01]); return; end
            if findstr(Par3,'Source'), K=11; else K=15; end %Par3=TY; Alt.:Destin.
            if findstr(Par3,'Flow'),   K=K+2;           end %Par3=TY; Alt.: Effort
            if i==1, VA=Par1'; else VA=Par1; end       %Spalten-Vektor erzeugen
       end; A2=0;                                      %K, VA und A2 sind Ergebnisse
  case {20}                                            %R-Element
       [i,j]=size(Par1);                               %Par1=Wert
       if strcmp(Par4,'off')                           %Par4=NL - linear ???
          if   findstr(Par2,'Scalar')                  %Par2=MU
	           if ~isscalar(Par1)||~isreal(Par1)||isstr(Par1)%skalar/reell/no_String?
                  errordlg([h 10 10 FT02],['R' FT01]); return; end           %Par3=TY
	           if findstr(Par3,'R-'), VA=Par1; K=20; else VA=1/Par1; K=22; end
          else
	           if i+j<3||i~=j||~isreal(Par1)||isstr(Par1)%reell/sym_Matrix/no_String?
                  errordlg([h 10 10 FT03],['R' FT01]); return; end               %TY?
	           if findstr(Par3,'R-'), VA=Par1; K=21;
               else                              %VA=inv(Par1) --> bei Ringstrukturen
                    NiNu=find(Par1~=0);          %z.B. Nichtdiagonalmatrizen mglich
                    VA(NiNu(:))=1./Par1(NiNu(:));% inf=Wert/0 vermeiden
                    VA=reshape(VA,i,i);          % Vektor --> Matrix
                    K=23;
               end
          end
       else                                            %Einstellung: nicht-linear!
          VA=0;                                        %Wert extern vorgeben
          if   findstr(Par2,'Scalar')                  %Par2=MU - skalar ???
               if findstr(Par3,'R-'), K=20; else K=22; end %Par3=TY
          else                                         % vektoriell!
               if findstr(Par3,'R-'), K=21; else K=23; end %TY?
          end
       end; A2=0;                                      %K, VA und A2 sind Ergebnisse
  case {30}                                       %I/C-Speicher
       PV0=Par2;                                  %direkte AW bergabe, da "evaluate"
       Par2=get_param(h,'MU');                    %indirekt, da sowieso String
       [i,j]=size(Par1);                          %Par1=Wert
       if   findstr(Par2,'Scalar')                %Par2=MU
	        if ~isscalar(Par1)||~isreal(Par1)||isstr(Par1) %skalar/reell/kein_String?
               errordlg([h 10 10 FT02],['I/C' FT01]); return; end
	        if findstr(Par3,'Integral'), VA=1/Par1; K=30; else VA=Par1; K=32; end
            if findstr(Par3,'C-'), K=K+1; end          %Par3=TY
       else
            if i+j<3||i~=j||~isreal(Par1)||isstr(Par1) %reell/sym_Matrix/kein_String?
               errordlg([h 10 10 FT03],['I/C' FT01]); return; end
	        if   findstr(Par3,'Integral')        %VA=inv(Par1) --> bei Ringstrukturen
                 NiNu=find(Par1~=0);             %z.B. Nichtdiagonalmatrizen mglich
                 VA(NiNu(:))=1./Par1(NiNu(:));   % inf=Wert/0 vermeiden
                 VA=reshape(VA,i,i); K=34;       % Vektor --> Matrix
            else VA=Par1; K=36;
            end
            if findstr(Par3,'C-'), K=K+1; end
       end
       if   strcmp(Par4,'off'), PV0=0;         %Kein Leistungsvariablen Anfangswert ?
       else                                                 %Eingabeprfung, PV0=AW
            if   findstr(Par2,'Scalar')                     %Par2=MU
	             if ~isscalar(PV0)||~isreal(PV0)||isstr(PV0) %skalar/reell/no_String?
                    errordlg([h 10 10 FT12],['I/C' FT01]); set_param(h,'AW','0');
                    return; end
                 PV0=PV0/VA; %Korrektur des AW wegen Reihenfolge:Integ-->Mult ntig
            else                               %Vektor/kein_Skalar/reell/kein_String?
                 if ~isvector(PV0)||isscalar(PV0)||~isreal(PV0)||isstr(PV0),
                    errordlg([h 10 10 FT13],['I/C' FT01]); set_param(h,'AW','0');
                    return; end
                 if sum(sum(VA-diag(diag(VA))))==0   %Diagonalmatrix erkannt!
                    [ii,jj]=size(PV0);               %PV0 Zeilen- o. Spaltenvektor?
                    if ii==1, PV0=PV0'; end          %SpaVek ntig wegen "diag"!
                    if i~=length(PV0)       %Passen Dimensionen VA und PV0 zusammen?
                       errordlg([h 10 10 FT15],['I/C' FT01]); set_param(h,'AW','0');
                       return; end
                    PV0=PV0./diag(VA);               %Automatische Korrektur mglich
                 else    %Hier keine einfache Korrektur von PV0 mit VA mglich, da
                         %VA keine Diagonal Matrix ist, deshalb Warnungsausgabe:
                    if j~=length(PV0)       %Passen Dimensionen VA und PV0 zusammen?
                       errordlg([h 10 10 FT15],['I/C' FT01]); set_param(h,'AW','0');
                       return; end
                    warndlg([h 10 10 FT14a FT14b 10 10 FT14c],['I/C' FT01]);
                 end
            end
       end; A2=PV0;                                    %K, VA und A2 sind Ergebnisse
  case {40}                                            %TF-Transformer
       NL=Par4(1:2); VN=Par4(3:4);                     %Par4 enthlt NL,VN mit 2 Zei!
       [i,j]=size(Par1);                               %Par1=Wert
       if strcmp(NL,'of')                              %NL=Maske_Par4 - linear ?
         if   findstr(Par2,'Scalar')                   %Par2=MU
	        if ~isscalar(Par1)||~isreal(Par1)||isstr(Par1) %skalar/reell/kein_String?
               errordlg([h 10 10 FT02],['TF' FT01]); return; end             %Par3=TY
	        if findstr(Par3,'Left'), VA=Par1; K=40; else VA=1/Par1; K=42; end
         else                                          %Parameter ist nicht skalar
            if isscalar(Par1)||~isreal(Par1)||isstr(Par1) %~skalar/reell/kein_String? 
               VMF=1; else VMF=0; end %Umkehrung der SkalarPrfung --> i+j==0 Test!!!
            if findstr(Par2,'Vector')&(VMF|~isvector(Par1)|i+j==0)     %Par2=MU
               errordlg([h 10 10 FT05],['TF' FT01]); return; end
            if findstr(Par2,'Matrix')&(VMF|isvector(Par1)|i+j<4)%Par2=MU,nicht i==j!!
               errordlg([h 10 10 FT16],['TF' FT01]); return; end
	        if    findstr(Par3,'Left'), VA=Par1; K=41; %bei left  & Vek./Mat. erkannt
            else                                 K=43; %bei right & Vek./Mat. erkannt
                  NiNu=find(Par1~=0);           %z.B. Nichtdiagonalmatrizen mglich
                  VA(NiNu(:))=1./Par1(NiNu(:)); % inf=Wert/0 vermeiden
                  if isvector(Par1) PrueLae=i+j-1; else PrueLae=i+j; end
                  if length(VA)~=PrueLae VA(PrueLae)=0; end %no reshape final zeros
                  VA=reshape(VA,i,j);           % Matrix wieder herstellen
            end                                 %VA=inv(Par1) -> bei Ringstrukturen
         end                                    %mglich, wenn nur Hauptdiagonale!
       else                                            %Einstellung nicht-linear!
         VA=0;                                         %Wert extern vorgeben
         if   findstr(Par2,'Scalar')                   %Par2=MU
	        if findstr(Par3,'Left'), K=40; else K=42; end %Par3=TY
         else                                   %Wert mu Vektor o. symm. Matrix sein
	        if findstr(Par3,'Left'), K=41; else K=43; end %Vektor/Matrix
         end
       end;
       if   strcmp(VN,'of') A2=[1.1 1.1];              %VN=Maske_Par5 - positiv ?
       else                 A2=[0.65 0.75]; end        %neg.: Maske Minus Vorzeichen
       SV2=num2str(K);                                 %K, VA und A2 sind Ergebnisse
       set_param([h '/KR'],'Value',SV2);               %Stringbergabe notwendig
  case {50}                                            %GY-Gyrator
       NL=Par4(1:2); VN=Par4(3:4);                     %Par4 enthlt NL,VN mit 2 Zei! 
       [i,j]=size(Par1);                               %Par1=Wert
       if strcmp(NL,'of')                              %NL=Maske_Par4 - linear ?
         if findstr(Par2,'Scalar')                     %Par2=MU
	        if ~isscalar(Par1)||~isreal(Par1)||isstr(Par1) %skalar/reell/kein_String?
               errordlg([h 10 10 FT02],['GY' FT01]); return; end             %Par3=TY
	        if findstr(Par3,'Outside'), VA=Par1; K=50; else VA=1/Par1; K=52; end
         else                                          %Parameter ist nicht skalar
            if isscalar(Par1)||~isreal(Par1)||isstr(Par1) %~skalar/reell/kein_String?
               VMF=1; else VMF=0; end %Umkehrung der SkalarPrfung --> i+j==0 Test!!!
            if findstr(Par2,'Vector')&(VMF|~isvector(Par1)|i+j==0)     %Par2=MU
               errordlg([h 10 10 FT05],['GY' FT01]); return; end
            if findstr(Par2,'Matrix')&(VMF|isvector(Par1)|i+j<4)%Par2=MU nicht i==j!!
               errordlg([h 10 10 FT16],['GY' FT01]); return; end
	        if   findstr(Par3,'Outside'), VA=Par1; K=51;%bei outside&Vek./Mat.erkannt
            else                                   K=53;%bei inside&Vek./Mat. erkannt
                 NiNu=find(Par1~=0);           %z.B. Nichtdiagonalmatrizen mglich
                 VA(NiNu(:))=1./Par1(NiNu(:)); % inf=Wert/0 vermeiden
                 VA=reshape(VA,i,j);           % Matrix wieder herstellen
            end                                %VA=inv(Par1) -> bei Ringstrukturen
         end                                   %mglich, wenn nur Hauptdiagonale
       else                                            %Einstellung nichtlinear!
         VA=0;                                         %Wert extern vorgeben
         if findstr(Par2,'Scalar')                     %Par2=MU
	        if findstr(Par3,'Outside'), K=50; else K=52; end %Par3=TY
         else                                   %Wert mu Vektor o. symm. Matrix sein
	        if findstr(Par3,'Outside'), K=51; else K=53; end %Vektor/Matrix
         end
       end
       if   strcmp(VN,'of') A2=[1.1 1.1];              %VN=Maske_Par5 - positiv ?
       else                 A2=[0.75 0.85]; end        %neg.: Maske Minus Vorzeichen
       SV2=num2str(K);                                 %K, VA und A2 sind Ergebnisse
       set_param([h '/KR'],'Value',SV2);               %Stringbergabe notwendig
  case {60}                                            %KN-Knoten (Par4=UM)
       if strcmp(Par4,'off')                           %Standard mit Ausgang X0=F0/E0
            if findstr(Par3,'0-'), K=60; else K=61; end %60: 0-Knoten / 61: 1-Knoten
       else if findstr(Par3,'0-'), K=62; else K=63; end %alternat. Eingang / kein X0
       end
       VA=Par1*10+Par2;                                %Zehner: ZU, Einer: AB
       FieldNames=fieldnames(get_param(h,'Dialogparameters')); % NodeBlockVersion ?
       if   sum(strcmp(FieldNames(:),'BI')), Par5=get_param(h,'BI'); %Schon BI ?
       else                                  Par5='off'; end %indirekt, da String
       if   strcmp(Par4,'on')&&strcmp(Par5,'on')       %'UM' und 'BI' sind 'on' ?
            if     Par2==2, A2=[0.72 0.86];            %   2 "Ausgnge"
            else            A2=[0.82 0.96]; end        % >=3 "Ausgnge"
       else A2=[1.1 1.1];                              %Ikone nicht verndern
       end                                             %K, VA und A2(Y): Ergebnisse
  case {70}                                            %RF-Element (R-Feld)
       W2=str2num(Par2(1:end-2));                      %Par2=[W2_TY] auspacken
       TY=Par2(end);
       if ~isscalar(W2)||~isreal(W2)||isstr(W2)%W2_Gesmtverst skalar/reell/no_String?
          errordlg([h 10 10 FT06 FT02],['RF' FT01]); return; end
       if   strcmp(Par4,'off')                         %Par4=NL - linear ?
            [i,j]=size(Par1);                          %Par1=Wert
            if i+j<3||i~=j||~isreal(Par1)||isstr(Par1) %sym_Matrix/reell/kein_String?
               errordlg([h 10 10 FT03],['RF' FT01]); return; end
            VA=Par1;                  %Felder: Parameter bereits "richtig" eingeben!
       else VA=0;                     %Einstellung nichtlinear / Wert extern vorgeben
       end
       if   TY~='M'                                    %Kausal: Mixed o. Flow/Effort
            if  strcmp(Par4,'off')&& i~=sum(Par3)      %Matrix <--> Vek.-Elemente ?
                errordlg([h 10 10 FT07],['RF' FT01]); return; end
	        if TY=='F', K=70; else K=72; end; KR=0;    %Kausal: Flow oder Effort
       else                                            %Mixed causal
            M1=Par3'; M2=M1(1:end); M3=M2(logical(M2&M2)); %Hintereinander zus.-fg.
            if strcmp(Par4,'off')&& i~=sum(M3)         %Matrix <--> Vek.-Elemente ?
               errordlg([h 10 10 FT08],['RF' FT01]); return; end
            K=76; KR=sum(Par3(1,:))+1;                 %KR = 1. Portnummer fr Effort
       end; A2=W2;                                     %K, VA und A2 sind Ergebnisse
       SV2=num2str(KR);                                %Stringbergabe notwendig
       set_param([h '/KR'] ,'Value',SV2);
  case {80}                                            %ICF-Element (IC-Feld)
       [i,j]=size(Par1);                               %Par1=VA
       if i+j<3||i~=j||~isreal(Par1)||isstr(Par1)      %sym_Matrix/reell/kein_String?
          errordlg([h 10 10 FT03],['ICF' FT01]); return; end
       VA=Par1;                        %Felder: Parameter bereits "richtig" eingeben!
       if     findstr(Par2,'IF-'),          ICF=2; else ICF=0; end;%Alterna.: CF-
       if     findstr(Par2,'Integral'),     IDM=1; 
       elseif findstr(Par2,'Differential'), IDM=0; else IDM=2; end;  %Alterna.: Mixed
       if   IDM~=2             %Par2:TY - Mixed o. Int/Diff causal
            if  i~=sum(Par3)   %Passen Matrix(Par1) und Vek.-Elemente(Par3=ANZ) zus.?
                errordlg([h 10 10 FT07],['ICF' FT01]); return; end
	        t=IDM+ICF;
            switch t, case {3}, K=80; case {1}, K=81; case {2}, K=82; case {0}, K=83;
                otherwise, errordlg([h 10 10 FT09],['ICF' FT01]); return; end
            KR=0;                                      %nicht mixed
       else                                            %Mixed causal
            M1=Par3'; M2=M1(1:end); M3=M2(logical(M2&M2)); %Hintereinander zus.-fg.
            if i~=sum(M3),     %Passen Matrix(Par1) und Vek.-Elemente(Anz=Par3) zus.?
               errordlg([h 10 10 FT08],['ICF' FT01]); return; end
            if ICF, K=88; else K=87; end %IF-mixed? / Kode fr F-Eingnge  (E: 86/89)
            KR=sum(Par3(1,:))+1; %KR = 1. Portnummer fr Effort  (Kodewechsel in KNK)
       end; A2=0;                                      %K, VA und A2 sind Ergebnisse
       SV2=num2str(KR);                                %Stringbergabe notwendig
       set_param([h '/KR'] ,'Value',SV2);
  case {90}                                            %AB (activated bond)
       if findstr(Par1,'E=0'), K=90; else K=91; end    %90: E-act. / 91: F-act.
       VA=0; A2=0;                                     %K, VA und A2 sind Ergebnisse
  otherwise, errordlg(FT00,'BGV2_Init'); return;
end                                                    %Switch-ENDE
SV=num2str(K);                                         %Stringbergabe notwendig
set_param([h '/K'],'Value',SV);                        %Aktion fr alle Flle gleich

Contact us at files@mathworks.com