├── example1.cir ├── example3.cir ├── example6.cir ├── example9.cir ├── example2.cir ├── example4.cir ├── Schematics ├── example1.png ├── example2.png ├── example3.png ├── example4.png ├── example5.png ├── example6.png ├── example7.png ├── example8.png ├── example9.png ├── example10.png ├── example11.png └── example12.png ├── example5.cir ├── example8.cir ├── example10.cir ├── example7.cir ├── example11.cir ├── example12.cir ├── Main.m ├── LICENSE ├── CHANGELOG.md ├── README.md ├── Standard_Analysis.m └── MonteCarlo.m /example1.cir: -------------------------------------------------------------------------------- 1 | Vs 1 0 12 2 | R1 1 2 1000 3 | R2 2 0 2000 4 | R3 2 0 2000 -------------------------------------------------------------------------------- /example3.cir: -------------------------------------------------------------------------------- 1 | Vb 1 0 12 2 | R1 1 2 10 3 | R2 2 0 20 4 | R3 2 0 50 5 | C1 2 0 47E-06 -------------------------------------------------------------------------------- /example6.cir: -------------------------------------------------------------------------------- 1 | V1 1 0 24 2 | V2 3 0 15 3 | R1 1 2 10000 4 | R2 2 3 8100 5 | R3 2 0 4700 -------------------------------------------------------------------------------- /example9.cir: -------------------------------------------------------------------------------- 1 | V1 1 0 24 2 | R1 1 2 10 3 | R2 2 3 20 4 | E1 2 0 1 2 5 5 | E2 3 0 2 3 10 -------------------------------------------------------------------------------- /example2.cir: -------------------------------------------------------------------------------- 1 | Vg 1 0 4 2 | Vx 3 2 6 3 | R1 1 2 1 4 | R2 2 0 4 5 | R3 3 0 2 6 | It 1 2 1 -------------------------------------------------------------------------------- /example4.cir: -------------------------------------------------------------------------------- 1 | Vin 3 0 5 2 | R2 3 2 1000 3 | R1 1 0 1000 4 | C1 1 0 1E-6 5 | C2 2 1 10E-6 -------------------------------------------------------------------------------- /Schematics/example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example1.png -------------------------------------------------------------------------------- /Schematics/example2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example2.png -------------------------------------------------------------------------------- /Schematics/example3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example3.png -------------------------------------------------------------------------------- /Schematics/example4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example4.png -------------------------------------------------------------------------------- /Schematics/example5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example5.png -------------------------------------------------------------------------------- /Schematics/example6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example6.png -------------------------------------------------------------------------------- /Schematics/example7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example7.png -------------------------------------------------------------------------------- /Schematics/example8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example8.png -------------------------------------------------------------------------------- /Schematics/example9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example9.png -------------------------------------------------------------------------------- /example5.cir: -------------------------------------------------------------------------------- 1 | V1 1 2 32 2 | R1 1 0 2 3 | R2 2 3 4 4 | R3 2 0 8 5 | V2 3 0 20 6 | E1 1 0 2 3 5 -------------------------------------------------------------------------------- /example8.cir: -------------------------------------------------------------------------------- 1 | V1 1 0 10 2 | C1 1 2 47E-06 3 | C2 1 2 22E-06 4 | R1 2 0 3300 5 | G1 1 0 1 2 4E-2 -------------------------------------------------------------------------------- /Schematics/example10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example10.png -------------------------------------------------------------------------------- /Schematics/example11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example11.png -------------------------------------------------------------------------------- /Schematics/example12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nik1106/MNA-MAT/HEAD/Schematics/example12.png -------------------------------------------------------------------------------- /example10.cir: -------------------------------------------------------------------------------- 1 | R1 1 2 5 2 | R2 1 3 10 3 | R3 2 0 15 4 | R4 3 0 20 5 | C1 2 3 47E-06 6 | V1 1 0 5 -------------------------------------------------------------------------------- /example7.cir: -------------------------------------------------------------------------------- 1 | V1 1 0 10 2 | C1 2 0 47E-06 3 | R1 1 2 10000 4 | G1 1 2 1 2 2E-4 5 | G2 1 2 1 0 4E-3 -------------------------------------------------------------------------------- /example11.cir: -------------------------------------------------------------------------------- 1 | V1 1 0 10 2 | R1 2 1 4 3 | R2 3 4 6 4 | R3 2 3 5 5 | R4 1 4 3 6 | V2 3 5 3 7 | R5 4 6 2 8 | R6 2 7 7 9 | R7 0 6 1 10 | L1 5 6 30e-3 11 | C1 4 0 10e-6 12 | C2 8 5 2e-6 13 | L2 7 8 50e-3 -------------------------------------------------------------------------------- /example12.cir: -------------------------------------------------------------------------------- 1 | R1 1 2 100 2 | R2 1 3 82 3 | L1 1 4 68e-3 4 | L2 1 3 68e-3 5 | C1 1 4 47e-6 6 | C2 2 5 300e-6 7 | C3 6 3 300e-6 8 | R3 4 6 47 9 | L3 5 4 22e-3 10 | L4 0 6 68e-3 11 | L5 7 3 33e-3 12 | R4 6 8 51 13 | C4 8 7 300e-6 14 | C5 1 8 47e-6 15 | V1 1 0 30 -------------------------------------------------------------------------------- /Main.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | close all; 4 | choice = input('<< Welcome to MNA-MAT - A SPICE netlist simulation tool >> \n 1. Standard Analysis \n 2. Monte Carlo Analysis \n 3. View the results of previous simulation \n'); 5 | switch(choice) 6 | case{1} 7 | run('Standard_Analysis.m'); 8 | case{2} 9 | run('MonteCarlo.m'); 10 | case{3} 11 | if(exist('Results.txt')) 12 | type('Results.txt'); 13 | elseif(exist('Results.xls')) 14 | open('Results.xls'); 15 | if(exist('MC_values_ode.txt')) 16 | type('MC_values_ode.txt'); 17 | end 18 | open('Voltages_graph.fig'); 19 | if(exist('Currents_graph.fig')) 20 | open('Currents_graph.fig'); 21 | end 22 | else 23 | disp('No results of previous simulation found'); 24 | end 25 | end -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Nikhil Chhabria 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | 4 | ## Unreleased 5 | 6 | ### September 5th, 2016 7 | 8 | ### Added 9 | - In __MonteCarlo.m__, seperate distribution choices for resistors and capacitors. 10 | - In __MonteCarlo.m__, option to keep resistor or capacitor values fixed at each run. 11 | 12 | ### Changed 13 | - In __MonteCarlo.m__, the uniform distribution for resistors and capacitors is now continuous rather than discrete. 14 | 15 | ### September 16th, 2016 16 | 17 | ### Added 18 | - __Inductors__ can now be used in the SPICE netlist. 19 | - __Current controlled voltage sources (H)__ can now be used in the SPICE netlist. 20 | - __Current controlled current sources (F)__ can now be used in the SPICE netlist. 21 | 22 | ### Changed 23 | - Removed unnecessary loops to improve speed. 24 | 25 | ### September 18th, 2016 26 | 27 | ### Added 28 | - Axes labels for transient plots. 29 | 30 | ### Changed 31 | - General code cleanup - removed unnecessary square brackets. 32 | 33 | ### September 20th, 2016 34 | 35 | ### Added 36 | - New example SPICE netlist (example11.cir) with associated schematic (example11.png), a complex RLC circuit. 37 | 38 | ### Changed 39 | - Minor changes. 40 | 41 | ### September 23rd, 2016 42 | 43 | ### Added 44 | - New example SPICE netlist (example12.cir) with associated schematic (example12.png), a complex RLC circuit. 45 | 46 | ### Changed 47 | - Minor changes. 48 | 49 | ### October 18th, 2016 50 | 51 | ### Changed 52 | - Minor aesthetic changes in the code and the generated output text files. 53 | 54 | ### November 26th, 2016 55 | ### Added 56 | - MIT License. 57 | 58 | ### Changed 59 | - Minor aesthetic improvements. 60 | - Minor changes for avoiding the 'symbolic:sym:sym:DeprecateExpressions' warning concerning sym command in MATLAB R2016a (MuPAD symbolic engine is now called using evalin command instead), and for support on future MATLAB releases. 61 | 62 | ### February 12th, 2017 63 | ### Changed 64 | - Removed all ^M characters in Main.m, Standard_Analysis.m and MonteCarlo.m using dos2unix. 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Logo](http://i.imgur.com/ykW0juV.png?1) 2 | # _MNA-MAT_ 3 | A SPICE netlist simulation tool for MATLAB 4 | 5 | ## MNA-MAT in action 6 | The netlist file being simulated is __example8.cir__ (included in this repository). As it is an RC circuit, the simulation type used is __Transient analysis__. 7 | 8 | ![alt text](https://github.com/nik1106/MNA-MAT/blob/master/Schematics/example8.png) ![alt text](http://i.imgur.com/2oqzSAk.png) 9 | 10 | ### Standard Analysis 11 | ![increment](http://imgur.com/OHJG8eu.gif) 12 | 13 | ### Monte Carlo Analysis 14 | ![increment](http://i.imgur.com/nYNlx0C.gif) 15 | ## About MNA-MAT 16 | MNA-MAT is a simulation tool designed in MATLAB for solving circuits described as SPICE netlists. It uses the algorithm of Modified Nodal Analysis (MNA). It accepts a file (.cir or .txt) with the SPICE netlist description of the circuit to be simulated. As of now, MNA-MAT supports the following circuit elements :- 17 | - Resistors (R) 18 | - Capacitors (C) 19 | - Inductors (L) 20 | - Independent voltage sources (V) 21 | - Independent current sources (I) 22 | - Voltage controlled voltage sources (VCVS) (E) 23 | - Voltage controlled current sources (VCCS) (I) 24 | - Current controlled voltage sources (CCVS) (H) 25 | - Current controlled current sources (CCCS) (F) 26 | 27 | MNA-MAT supports the following simulation types as of present :- 28 | * DC bias point (for purely resistive circuits) 29 | * Transient analysis (for pure C, pure L, RC, RL, LC or RLC circuits) 30 | * Monte Carlo analysis (done using one of the above, again based on the type of circuit) 31 | 32 | __Note :-__ This tool works only on versions of MATLAB from R2014b onwards. The voltage source currents are taken in conventional current direction i.e. inside the source, __negative__ to __positive__ terminal. 33 | 34 | ## Features 35 | 1. Easy to use and then analyse results. 36 | 2. Accurate (a bunch of circuits were simulated on this tool and then on TopSpice, the results were always identical). 37 | 3. Saves the results of the previous run simulation. 38 | 4. No installation or initial setup required. You can start using the tool as soon as you download it. 39 | 5. No need to add SPICE commands like __.TRAN__ or __.DC__. A text description of the circuit is enough. 40 | 6. The written code is flexible - it allows room to make changes and add more features if necessary. 41 | 42 | ## Directions for use 43 | 1. Before you start using the tool, make sure you have read-write permissions in the folder where the tool files are stored. If you aren't sure about this, simply start up MATLAB as Administrator. 44 | 2. Place the netlist file (.cir or .txt) you wish to simulate in the folder where the tool files are stored. 45 | 3. Run the file Main.m. 46 | 4. Simply follow the on-screen instructions. 47 | 48 | ## What's included 49 | 1. The three MATLAB tool files. 50 | 2. A set of 12 examples (.cir SPICE netlists) along with schematics (.png images) of the same. 51 | 52 | ## Just a Request 53 | If you find this tool useful, or at least think it to be ambitious, please consider leaving a star or suggesting changes. 54 | 55 | __Thank You__ 56 | -------------------------------------------------------------------------------- /Standard_Analysis.m: -------------------------------------------------------------------------------- 1 | %%Delete the results of previous simulation, if any 2 | if(exist('Results.txt')) 3 | delete('Results.txt'); 4 | elseif(exist('Results.xls')) 5 | delete('Results.xls'); 6 | if(exist('MC_values_ode.txt')) 7 | delete('MC_values_ode.txt'); 8 | end 9 | delete('Voltages_graph.fig'); 10 | if(exist('Currents_graph.fig')) 11 | delete('Currents_graph.fig'); 12 | end 13 | end 14 | %%----------------------------------------------------------------------------- 15 | prompt='Enter the file name - '; 16 | fname=input(prompt,'s'); 17 | netlist_fileID=fopen(fname); 18 | netlist=textscan(netlist_fileID,'%s %s %s %s %s %s'); 19 | fclose(netlist_fileID); 20 | fileID1=fopen('Element_indep.txt','wt+'); %Create an empty text file Element_indep.txt for passive elements and independent sources 21 | fileID2=fopen('VCVS.txt','wt+'); %Create an empty text file VCVS.txt for voltage controlled voltage sources 22 | fileID3=fopen('VCCS.txt','wt+'); %Create an empty text file VCCS.txt for voltage controlled current sources 23 | fileID4=fopen('CCVS.txt','wt+'); %Create an empty text file CCVS.txt for current controlled voltage sources 24 | fileID5=fopen('CCCS.txt','wt+'); %Create an empty text file CCCS.txt for current controlled current sources 25 | %%----------------------------------------------------------------------------- 26 | %%Initialize 27 | num_Elements=0; %Number of passive elements 28 | num_V=0; %Number of independent voltage sources 29 | num_I=0; %Number of independent current sources 30 | num_Nodes=0; %Number of nodes, excluding ground (node 0) 31 | num_VCVS=0; %Number of voltage controlled voltage sources 32 | num_VCCS=0; %Number of voltage controlled current sources 33 | num_CCVS=0; %Number of current controlled voltage sources 34 | num_CCCS=0; %Number of current controlled current sources 35 | num_L=0; %Number of inductors 36 | %%----------------------------------------------------------------------------- 37 | for i=1:length(netlist{1}) 38 | s=netlist{1}{i}; 39 | switch(s(1)) 40 | case{'R','L','C','V','I'} %For passive elements and independent sources 41 | fprintf(fileID1,[netlist{1}{i} ' ' netlist{2}{i} ' ' ... 42 | netlist{3}{i} ' ' netlist{4}{i} '\n']); 43 | case{'E'} %For voltage controlled voltage sources 44 | fprintf(fileID2,[netlist{1}{i} ' ' netlist{2}{i} ' ' ... 45 | netlist{3}{i} ' ' netlist{4}{i} ' ' netlist{5}{i} ' ' ... 46 | netlist{6}{i} '\n']); 47 | case{'G'} %For voltage controlled current sources 48 | fprintf(fileID3,[netlist{1}{i} ' ' netlist{2}{i} ' ' ... 49 | netlist{3}{i} ' ' netlist{4}{i} ' ' netlist{5}{i} ' ' ... 50 | netlist{6}{i} '\n']); 51 | case{'H'} %For current controlled voltage sources 52 | fprintf(fileID4,[netlist{1}{i} ' ' netlist{2}{i} ' ' ... 53 | netlist{3}{i} ' ' netlist{4}{i} ' ' netlist{5}{i} '\n']); 54 | case{'F'} %For current controlled current sources 55 | fprintf(fileID5,[netlist{1}{i} ' ' netlist{2}{i} ' ' ... 56 | netlist{3}{i} ' ' netlist{4}{i} ' ' netlist{5}{i} '\n']); 57 | end 58 | end 59 | %%----------------------------------------------------------------------------- 60 | %%Read the data from Element_indep.txt text file 61 | [Name,N1,N2,value]=textread('Element_indep.txt','%s %s %s %s'); 62 | for i=1:length(Name) 63 | switch(Name{i}(1)) 64 | case{'R','L','C'} 65 | num_Elements=num_Elements+1; 66 | Element(num_Elements).Name=Name{i}; 67 | Element(num_Elements).Node1=str2num(N1{i}); 68 | Element(num_Elements).Node2=str2num(N2{i}); 69 | Element(num_Elements).Value=str2double(value{i}); 70 | if(Name{i}(1)=='L') 71 | num_L=num_L+1; 72 | Inductor(num_L).Name=Name{i}; 73 | Inductor(num_L).N1=str2num(N1{i}); 74 | Inductor(num_L).N2=str2num(N2{i}); 75 | Inductor(num_L).Value=str2double(value{i}); 76 | end 77 | case{'V'} 78 | num_V=num_V+1; 79 | Volt_source(num_V).Name=Name{i}; 80 | Volt_source(num_V).Node1=str2num(N1{i}); 81 | Volt_source(num_V).Node2=str2num(N2{i}); 82 | Volt_source(num_V).Value=str2double(value{i}); 83 | 84 | case{'I'} 85 | num_I=num_I+1; 86 | Current_source(num_I).Name=Name{i}; 87 | Current_source(num_I).Node1=str2num(N1{i}); 88 | Current_source(num_I).Node2=str2num(N2{i}); 89 | Current_source(num_I).Value=str2double(value{i}); 90 | end 91 | num_Nodes=max(str2num(N1{i}),max(str2num(N2{i}),num_Nodes)); 92 | end 93 | %%----------------------------------------------------------------------------- 94 | %%Read the data from VCVS.txt text file 95 | [Name,N1,N2,NC1,NC2,Gain]=textread('VCVS.txt','%s %s %s %s %s %s'); 96 | num_VCVS=length(Name); 97 | for i=1:num_VCVS 98 | VCVS(i).Name=Name{i}; 99 | VCVS(i).N1=str2num(N1{i}); 100 | VCVS(i).N2=str2num(N2{i}); 101 | VCVS(i).NC1=str2num(NC1{i}); 102 | VCVS(i).NC2=str2num(NC2{i}); 103 | VCVS(i).Gain=str2double(Gain{i}); 104 | num_Nodes=max(str2num(N1{i}),max(str2num(N2{i}),num_Nodes)); 105 | end 106 | %%----------------------------------------------------------------------------- 107 | %%Read the data from VCCS.txt text file 108 | [Name,N1,N2,NC1,NC2,Transconductance]=textread('VCCS.txt','%s %s %s %s %s %s'); 109 | num_VCCS=length(Name); 110 | for i=1:num_VCCS 111 | VCCS(i).Name=Name{i}; 112 | VCCS(i).N1=str2num(N1{i}); 113 | VCCS(i).N2=str2num(N2{i}); 114 | VCCS(i).NC1=str2num(NC1{i}); 115 | VCCS(i).NC2=str2num(NC2{i}); 116 | VCCS(i).Transconductance=str2double(Transconductance{i}); 117 | num_Nodes=max(str2num(N1{i}),max(str2num(N2{i}),num_Nodes)); 118 | end 119 | %%----------------------------------------------------------------------------- 120 | %%Read the data from CCVS.txt text file 121 | [Name,N1,N2,Vcontrol,Transresistance]=textread('CCVS.txt','%s %s %s %s %s'); 122 | num_CCVS=length(Name); 123 | for i=1:num_CCVS 124 | CCVS(i).Name=Name{i}; 125 | CCVS(i).N1=str2num(N1{i}); 126 | CCVS(i).N2=str2num(N2{i}); 127 | CCVS(i).Vcontrol=Vcontrol{i}; 128 | CCVS(i).Transresistance=str2double(Transresistance{i}); 129 | num_Nodes=max(str2num(N1{i}),max(str2num(N2{i}),num_Nodes)); 130 | end 131 | %%----------------------------------------------------------------------------- 132 | %%Read the data from CCCS.txt text file 133 | [Name,N1,N2,Vcontrol,Gain]=textread('CCCS.txt','%s %s %s %s %s'); 134 | num_CCCS=length(Name); 135 | for i=1:num_CCCS 136 | CCCS(i).Name=Name{i}; 137 | CCCS(i).N1=str2num(N1{i}); 138 | CCCS(i).N2=str2num(N2{i}); 139 | CCCS(i).Vcontrol=Vcontrol{i}; 140 | CCCS(i).Gain=str2double(Gain{i}); 141 | num_Nodes=max(str2num(N1{i}),max(str2num(N2{i}),num_Nodes)); 142 | end 143 | %%----------------------------------------------------------------------------- 144 | %%Close the no longer required text files and then delete them 145 | fclose(fileID1); 146 | fclose(fileID2); 147 | fclose(fileID3); 148 | fclose(fileID4); 149 | fclose(fileID5); 150 | delete('Element_indep.txt'); 151 | delete('VCVS.txt'); 152 | delete('VCCS.txt'); 153 | delete('CCVS.txt'); 154 | delete('CCCS.txt'); 155 | %%----------------------------------------------------------------------------- 156 | %%Create the equations for the independent voltage sources and apply KCL at the nodes 157 | node_equation=cell(num_Nodes,1); 158 | volt_equation=cell(num_V,1); 159 | for i=1:num_V 160 | switch((Volt_source(i).Node1==0)||(Volt_source(i).Node2==0)) 161 | case{1} 162 | if(Volt_source(i).Node1==0) 163 | volt=['v_' num2str(Volt_source(i).Node2) '=' '-' num2str(Volt_source(i).Value)]; 164 | node_equation{Volt_source(i).Node2}=[node_equation{Volt_source(i).Node2} ... 165 | '-' 'i_' Volt_source(i).Name]; 166 | else 167 | volt=['v_' num2str(Volt_source(i).Node1) '=' num2str(Volt_source(i).Value)]; 168 | node_equation{Volt_source(i).Node1}=[node_equation{Volt_source(i).Node1} ... 169 | '+' 'i_' Volt_source(i).Name]; 170 | end 171 | volt_equation{i}=volt; 172 | case{0} 173 | volt=['v_' num2str(Volt_source(i).Node1) '-' ... 174 | 'v_' num2str(Volt_source(i).Node2) '=' num2str(Volt_source(i).Value)]; 175 | volt_equation{i}=volt; 176 | node_equation{Volt_source(i).Node1}=[node_equation{Volt_source(i).Node1} ... 177 | '+' 'i_' Volt_source(i).Name]; 178 | node_equation{Volt_source(i).Node2}=[node_equation{Volt_source(i).Node2} ... 179 | '-' 'i_' Volt_source(i).Name]; 180 | end 181 | end 182 | %%----------------------------------------------------------------------------- 183 | %%Create the equations for the voltage controlled voltage sources and apply KCL at the nodes 184 | VCVS_equation=cell(num_VCVS,1); 185 | for i=1:num_VCVS 186 | switch((VCVS(i).N1==0)||(VCVS(i).N2==0)) 187 | case{1} 188 | if(VCVS(i).N1==0) 189 | switch((VCVS(i).NC1==0)||(VCVS(i).NC2==0)) 190 | case{1} 191 | if(VCVS(i).NC1==0) 192 | volt=['-' 'v_' num2str(VCVS(i).N2) '-' num2str(VCVS(i).Gain) ... 193 | '*' '(' '-' 'v_' num2str(VCVS(i).NC2) ')']; 194 | else 195 | volt=['-' 'v_' num2str(VCVS(i).N2) '-' num2str(VCVS(i).Gain) ... 196 | '*' '(' 'v_' num2str(VCVS(i).NC1) ')']; 197 | end 198 | case{0} 199 | volt=['-' 'v_' num2str(VCVS(i).N2) '-' num2str(VCVS(i).Gain) ... 200 | '*' '(' 'v_' num2str(VCVS(i).NC1) '-' 'v_' num2str(VCVS(i).NC2) ')']; 201 | end 202 | node_equation{VCVS(i).N2}=[node_equation{VCVS(i).N2} '-' 'i_' VCVS(i).Name]; 203 | else 204 | switch((VCVS(i).NC1==0)||(VCVS(i).NC2==0)) 205 | case{1} 206 | if(VCVS(i).NC1==0) 207 | volt=['v_' num2str(VCVS(i).N1) '-' num2str(VCVS(i).Gain) ... 208 | '*' '(' '-' 'v_' num2str(VCVS(i).NC2) ')']; 209 | else 210 | volt=['v_' num2str(VCVS(i).N1) '-' num2str(VCVS(i).Gain) ... 211 | '*' '(' 'v_' num2str(VCVS(i).NC1) ')']; 212 | end 213 | case{0} 214 | volt=['v_' num2str(VCVS(i).N1) '-' num2str(VCVS(i).Gain) ... 215 | '*' '(' 'v_' num2str(VCVS(i).NC1) '-' 'v_' num2str(VCVS(i).NC2) ')']; 216 | end 217 | node_equation{VCVS(i).N1}=[node_equation{VCVS(i).N1} '+' 'i_' VCVS(i).Name]; 218 | end 219 | case{0} 220 | switch((VCVS(i).NC1==0)||(VCVS(i).NC2==0)) 221 | case{1} 222 | if(VCVS(i).NC1==0) 223 | volt=['v_' num2str(VCVS(i).N1) '-' 'v_' num2str(VCVS(i).N2) '-' ... 224 | num2str(VCVS(i).Gain) '*' '(' '-' 'v_' num2str(VCVS(i).NC2) ')']; 225 | else 226 | volt=['v_' num2str(VCVS(i).N1) '-' 'v_' num2str(VCVS(i).N2) '-' ... 227 | num2str(VCVS(i).Gain) '*' '(' 'v_' num2str(VCVS(i).NC1) ')']; 228 | end 229 | case{0} 230 | volt=['v_' num2str(VCVS(i).N1) '-' 'v_' num2str(VCVS(i).N2) '-' ... 231 | num2str(VCVS(i).Gain) '*' '(' 'v_' num2str(VCVS(i).NC1) '-' 'v_' num2str(VCVS(i).NC2) ')']; 232 | end 233 | node_equation{VCVS(i).N1}=[node_equation{VCVS(i).N1} '+' 'i_' VCVS(i).Name]; 234 | node_equation{VCVS(i).N2}=[node_equation{VCVS(i).N2} '-' 'i_' VCVS(i).Name]; 235 | end 236 | VCVS_equation{i}=volt; 237 | end 238 | %%----------------------------------------------------------------------------- 239 | %%Create the equations for the current controlled voltage sources and apply KCL at the nodes 240 | CCVS_equation=cell(num_CCVS,1); 241 | for i=1:num_CCVS 242 | switch((CCVS(i).N1==0)||(CCVS(i).N2==0)) 243 | case{1} 244 | if(CCVS(i).N1==0) 245 | volt=['v_' num2str(CCVS(i).N2) '+' '(' num2str(CCVS(i).Transresistance) '*' 'i_' CCVS(i).Vcontrol ')']; 246 | node_equation{CCVS(i).N2}=[node_equation{CCVS(i).N2} ... 247 | '-' 'i_' CCVS(i).Name]; 248 | else 249 | volt=['v_' num2str(CCVS(i).N1) '-' '(' num2str(CCVS(i).Transresistance) '*' 'i_' CCVS(i).Vcontrol ')']; 250 | node_equation{CCVS(i).N1}=[node_equation{CCVS(i).N1} ... 251 | '+' 'i_' CCVS(i).Name]; 252 | end 253 | CCVS_equation{i}=volt; 254 | case{0} 255 | volt=['v_' num2str(CCVS(i).N1) '-' ... 256 | 'v_' num2str(CCVS(i).N2) '-' '(' num2str(CCVS(i).Transresistance) '*' 'i_' CCVS(i).Vcontrol ')']; 257 | CCVS_equation{i}=volt; 258 | node_equation{CCVS(i).N1}=[node_equation{CCVS(i).N1} ... 259 | '+' 'i_' CCVS(i).Name]; 260 | node_equation{CCVS(i).N2}=[node_equation{CCVS(i).N2} ... 261 | '-' 'i_' CCVS(i).Name]; 262 | end 263 | end 264 | %%----------------------------------------------------------------------------- 265 | solver_flag=0; %A flag used for deciding which solver to finally use 266 | %solver_flag=0 => Purely resistive circuit, use solve for the equations 267 | %solver_flag=1 => Pure C, pure L, LC, RC, RL or RLC circuit, use ode15i for the equations 268 | %%----------------------------------------------------------------------------- 269 | %%Add the passive element currents using KCL to the node equations, and make the equations for inductors 270 | L_equation=cell(num_L,1); 271 | L_ctr=0; 272 | for i=1:num_Elements 273 | switch(Element(i).Name(1)) 274 | case{'R'} 275 | switch((Element(i).Node1==0)||(Element(i).Node2==0)) 276 | case{0} 277 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} '+' '(' ... 278 | 'v_' num2str(Element(i).Node2) '-' 'v_' ... 279 | num2str(Element(i).Node1) ')' '/' num2str(Element(i).Value)]; 280 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} '+' '(' ... 281 | 'v_' num2str(Element(i).Node1) '-' 'v_' ... 282 | num2str(Element(i).Node2) ')' '/' num2str(Element(i).Value)]; 283 | case{1} 284 | if(Element(i).Node1==0) 285 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} ... 286 | '-' '(' 'v_' num2str(Element(i).Node2) ')' '/' num2str(Element(i).Value)]; 287 | else 288 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} ... 289 | '-' '(' 'v_' num2str(Element(i).Node1) ')' '/' num2str(Element(i).Value)]; 290 | end 291 | end 292 | case{'C'} 293 | if(solver_flag==0) 294 | solver_flag=1; 295 | end 296 | switch((Element(i).Node1==0)||(Element(i).Node2==0)) 297 | case{0} 298 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} ... 299 | '+' num2str(Element(i).Value) '*' '(' 'vp(' num2str(Element(i).Node2) ')' ... 300 | '-' 'vp(' num2str(Element(i).Node1) ')' ')']; 301 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} ... 302 | '+' num2str(Element(i).Value) '*' '(' 'vp(' num2str(Element(i).Node1) ')' ... 303 | '-' 'vp(' num2str(Element(i).Node2) ')' ')']; 304 | case{1} 305 | if(Element(i).Node1==0) 306 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} ... 307 | '-' num2str(Element(i).Value) '*' '(' 'vp(' num2str(Element(i).Node2) ')' ')']; 308 | else 309 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} ... 310 | '-' num2str(Element(i).Value) '*' '(' 'vp(' num2str(Element(i).Node1) ')' ')']; 311 | end 312 | end 313 | case{'L'} 314 | if(solver_flag==0) 315 | solver_flag=1; 316 | end 317 | L_ctr=L_ctr+1; 318 | switch((Element(i).Node1==0)||(Element(i).Node2==0)) 319 | case{0} 320 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} '-' 'i_' Element(i).Name]; 321 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} '+' 'i_' Element(i).Name]; 322 | L_equation{L_ctr}=['v_' num2str(Element(i).Node1) '-' 'v_' num2str(Element(i).Node2) '-' ... 323 | '(' num2str(Element(i).Value) '*' 'ip(' num2str(L_ctr) ')' ')']; 324 | case{1} 325 | if(Element(i).Node1==0) 326 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} '+' 'i_' Element(i).Name]; 327 | L_equation{L_ctr}=['-' 'v_' num2str(Element(i).Node2) '-' ... 328 | '(' num2str(Element(i).Value) '*' 'ip(' num2str(L_ctr) ')' ')']; 329 | else 330 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} '-' 'i_' Element(i).Name]; 331 | L_equation{L_ctr}=['v_' num2str(Element(i).Node1) '-' ... 332 | '(' num2str(Element(i).Value) '*' 'ip(' num2str(L_ctr) ')' ')']; 333 | end 334 | end 335 | end 336 | end 337 | %%----------------------------------------------------------------------------- 338 | %%Add the independent current sources using KCL to the node equations 339 | for i=1:num_I 340 | switch((Current_source(i).Node1==0)||(Current_source(i).Node2==0)) 341 | case{1} 342 | if(Current_source(i).Node1==0) 343 | node_equation{Current_source(i).Node2}=[node_equation{Current_source(i).Node2} ... 344 | '+' num2str(Current_source(i).Value)]; 345 | else 346 | node_equation{Current_source(i).Node1}=[node_equation{Current_source(i).Node1} ... 347 | '-' num2str(Current_source(i).Value)]; 348 | end 349 | case{0} 350 | node_equation{Current_source(i).Node1}=[node_equation{Current_source(i).Node1} ... 351 | '-' num2str(Current_source(i).Value)]; 352 | node_equation{Current_source(i).Node2}=[node_equation{Current_source(i).Node2} ... 353 | '+' num2str(Current_source(i).Value)]; 354 | end 355 | end 356 | %%----------------------------------------------------------------------------- 357 | %%Next, add the voltage controlled current sources using KCL to the node equations 358 | for i=1:num_VCCS 359 | switch((VCCS(i).N1==0)||(VCCS(i).N2==0)) 360 | case{1} 361 | if(VCCS(i).N1==0) 362 | switch((VCCS(i).NC1==0)||(VCCS(i).NC2==0)) 363 | case{1} 364 | if(VCCS(i).NC1==0) 365 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 366 | num2str(VCCS(i).Transconductance) '*' '(' '-' 'v_' num2str(VCCS(i).NC2) ')']; 367 | else 368 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 369 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) ')']; 370 | end 371 | case{0} 372 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 373 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) '-' ... 374 | 'v_' num2str(VCCS(i).NC2) ')']; 375 | end 376 | else 377 | switch((VCCS(i).NC1==0)||(VCCS(i).NC2==0)) 378 | case{1} 379 | if(VCCS(i).NC1==0) 380 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 381 | num2str(VCCS(i).Transconductance) '*' '(' '-' 'v_' num2str(VCCS(i).NC2) ')']; 382 | else 383 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 384 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) ')']; 385 | end 386 | case{0} 387 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 388 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) ... 389 | '-' 'v_' num2str(VCCS(i).NC2) ')']; 390 | end 391 | end 392 | case{0} 393 | switch((VCCS(i).NC1==0)||(VCCS(i).NC2==0)) 394 | case{1} 395 | if(VCCS(i).NC1==0) 396 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 397 | num2str(VCCS(i).Transconductance) '*' '(' '-' 'v_' num2str(VCCS(i).NC2) ')']; 398 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 399 | num2str(VCCS(i).Transconductance) '*' '(' '-' 'v_' num2str(VCCS(i).NC2) ')']; 400 | else 401 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 402 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) ')']; 403 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 404 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) ')']; 405 | end 406 | case{0} 407 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 408 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) '-' ... 409 | 'v_' num2str(VCCS(i).NC2) ')']; 410 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 411 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) '-' ... 412 | 'v_' num2str(VCCS(i).NC2) ')']; 413 | end 414 | end 415 | end 416 | %%----------------------------------------------------------------------------- 417 | %%Finally, add the current controlled current sources using KCL to the node equations 418 | for i=1:num_CCCS 419 | switch((CCCS(i).N1==0)||(CCCS(i).N2==0)) 420 | case{1} 421 | if(CCCS(i).N1==0) 422 | node_equation{CCCS(i).N2}=[node_equation{CCCS(i).N2} ... 423 | '+' '(' num2str(CCCS(i).Gain) '*' 'i_' CCCS(i).Vcontrol ')']; 424 | else 425 | node_equation{CCCS(i).N1}=[node_equation{CCCS(i).N1} ... 426 | '-' '(' num2str(CCCS(i).Gain) '*' 'i_' CCCS(i).Vcontrol ')']; 427 | end 428 | case{0} 429 | node_equation{CCCS(i).N1}=[node_equation{CCCS(i).N1} ... 430 | '-' '(' num2str(CCCS(i).Gain) '*' 'i_' CCCS(i).Vcontrol ')']; 431 | node_equation{CCCS(i).N2}=[node_equation{CCCS(i).N2} ... 432 | '+' '(' num2str(CCCS(i).Gain) '*' 'i_' CCCS(i).Vcontrol ')']; 433 | end 434 | end 435 | %%----------------------------------------------------------------------------- 436 | %%If solver_flag=0 (purely resistive circuit), add the RHS('=0') to each 437 | %%nodal KCL equation, to each VCVS equation, and to each CCVS equation 438 | if(solver_flag==0) 439 | for i=1:length(node_equation) 440 | node_equation{i}=[node_equation{i} '=' '0']; 441 | end 442 | for i=1:length(VCVS_equation) 443 | VCVS_equation{i}=[VCVS_equation{i} '=' '0']; 444 | end 445 | for i=1:length(CCVS_equation) 446 | CCVS_equation{i}=[CCVS_equation{i} '=' '0']; 447 | end 448 | %%Else if solver_flag=1 (Pure C, pure L, LC, RC, RL or RLC circuit), do NOT add the RHS ('=0') 449 | %%to each nodal KCL equation, to each VCVS equation, to each CCVS equation and to each inductor equation, instead replace 450 | %%the node voltage terms v_1,v_2,...v_num_Nodes in LHS of all the equations with v(1),v(2),...v(num_Nodes) respectively, 451 | %%modify each independent voltage source equation to only LHS [no RHS ('=0')] (similar to all the other equations), 452 | %%also replace the independent voltage source current terms with v(num_Nodes+j) (j=1:num_V) 453 | %%VCVS current terms with v(num_Nodes+num_V+j) (j=1:num_VCVS) 454 | %%CCVS current terms with v(num_Nodes+num_V+num_VCVS+j) (j=1:num_CCVS) 455 | %%and inductor current terms with v(num_Nodes+num_V+num_VCVS+num_CCVS+j) (j=1:num_L) 456 | elseif(solver_flag==1) 457 | for i=1:num_Nodes %For each nodal KCL equation (only LHS) 458 | for j=1:num_Nodes 459 | node_equation{i}=strrep(node_equation{i},['v_' num2str(j)],['v(' num2str(j) ')']); 460 | end 461 | for j=1:num_V 462 | node_equation{i}=strrep(node_equation{i},['i_' Volt_source(j).Name],['v(' num2str(num_Nodes+j) ')']); 463 | end 464 | for j=1:num_VCVS 465 | node_equation{i}=strrep(node_equation{i},['i_' VCVS(j).Name],['v(' num2str(num_Nodes+num_V+j) ')']); 466 | end 467 | for j=1:num_CCVS 468 | node_equation{i}=strrep(node_equation{i},['i_' CCVS(j).Name],['v(' num2str(num_Nodes+num_V+num_VCVS+j) ')']); 469 | end 470 | for j=1:num_L 471 | node_equation{i}=strrep(node_equation{i},['i_' Inductor(j).Name],['v(' num2str(num_Nodes+num_V+num_VCVS+num_CCVS+j) ')']); 472 | end 473 | end 474 | for i=1:num_V %For each independent voltage source equation 475 | for j=1:num_Nodes 476 | volt_equation{i}=strrep(volt_equation{i},['v_' num2str(j)],['v(' num2str(j) ')']); 477 | end 478 | volt_equation{i}=strrep(volt_equation{i},'=','-'); %Modify each independent voltage source equation to only LHS [no RHS ('=0')] 479 | end 480 | for i=1:num_VCVS %For each VCVS equation (only LHS) 481 | for j=1:num_Nodes 482 | VCVS_equation{i}=strrep(VCVS_equation{i},['v_' num2str(j)],['v(' num2str(j) ')']); 483 | end 484 | end 485 | for i=1:num_CCVS %For each CCVS equation (only LHS) 486 | for j=1:num_Nodes 487 | CCVS_equation{i}=strrep(CCVS_equation{i},['v_' num2str(j)],['v(' num2str(j) ')']); 488 | end 489 | for j=1:num_V 490 | CCVS_equation{i}=strrep(CCVS_equation{i},['i_' Volt_source(j).Name],['v(' num2str(num_Nodes+j) ')']); 491 | end 492 | for j=1:num_VCVS 493 | CCVS_equation{i}=strrep(CCVS_equation{i},['i_' VCVS(j).Name],['v(' num2str(num_Nodes+num_V+j) ')']); 494 | end 495 | for j=1:num_CCVS 496 | CCVS_equation{i}=strrep(CCVS_equation{i},['i_' CCVS(j).Name],['v(' num2str(num_Nodes+num_V+num_VCVS+j) ')']); 497 | end 498 | end 499 | for i=1:num_L %For each inductor equation (only LHS) 500 | for j=1:num_Nodes 501 | L_equation{i}=strrep(L_equation{i},['v_' num2str(j)],['v(' num2str(j) ')']); 502 | end 503 | end 504 | end 505 | %%----------------------------------------------------------------------------- 506 | eqn=cell(num_Nodes+num_V+num_VCVS+num_CCVS+num_L,1); 507 | for i=1:num_Nodes 508 | eqn{i}=evalin(symengine,node_equation{i}); 509 | end 510 | for i=1:num_V 511 | eqn{num_Nodes+i}=evalin(symengine,volt_equation{i}); 512 | end 513 | for i=1:num_VCVS 514 | eqn{num_Nodes+num_V+i}=evalin(symengine,VCVS_equation{i}); 515 | end 516 | for i=1:num_CCVS 517 | eqn{num_Nodes+num_V+num_VCVS+i}=evalin(symengine,CCVS_equation{i}); 518 | end 519 | for i=1:num_L 520 | eqn{num_Nodes+num_V+num_VCVS+num_CCVS+i}=evalin(symengine,L_equation{i}); 521 | end 522 | %%----------------------------------------------------------------------------- 523 | switch(solver_flag) 524 | case{0} 525 | %Create the symbolic variables for node voltages and currents through voltage sources 526 | variables='syms'; 527 | for i=1:num_Nodes 528 | variables=[variables ' ' 'v_' num2str(i)]; 529 | end 530 | for i=1:num_V 531 | variables=[variables ' ' 'i_' Volt_source(i).Name]; 532 | end 533 | for i=1:num_VCVS 534 | variables=[variables ' ' 'i_' VCVS(i).Name]; 535 | end 536 | for i=1:num_CCVS 537 | variables=[variables ' ' 'i_' CCVS(i).Name]; 538 | end 539 | eval(variables); 540 | %---------------------------------------------- 541 | %Create a row vector var of the symbolic variables created above - to be used in solve 542 | var_string=['var=[' variables(6:end) ']']; 543 | eval(var_string); 544 | %---------------------------------------------- 545 | %Create the symbolic variables for the symbolic equations 546 | equations='syms'; 547 | for i=1:(num_Nodes+num_V+num_VCVS+num_CCVS) 548 | equations=[equations ' ' 'eqn' num2str(i)]; 549 | end 550 | eval(equations); 551 | %---------------------------------------------- 552 | %Create a row vector eqn_solve of the equation symbolic variables 553 | interm_string=['eqn_solve=[' equations(6:end) ']']; 554 | eval(interm_string); 555 | %---------------------------------------------- 556 | %Assign the equation symbolic variables with the corresponding symbolic equations 557 | for i=1:(num_Nodes+num_V+num_VCVS+num_CCVS) 558 | eqn_string=['eqn' num2str(i) '=' 'eqn{' num2str(i) '}']; 559 | eval(eqn_string); 560 | end 561 | %---------------------------------------------- 562 | %Solve the symbolic linear equations using solve 563 | sol=solve(eval(eqn_solve),var); 564 | %Note :- We use eval(eqn_solve) to substitute the symbolic equation associated with 565 | %each equation symbolic variable 566 | %---------------------------------------------- 567 | F=fopen('Results.txt','wt+'); %Create an empty text file Results.txt 568 | date=datetime('now'); 569 | date_string=datestr(date); 570 | fprintf(F,date_string); 571 | fprintf(F,'\n'); 572 | fprintf(F,['File name : ' fname]); 573 | fprintf(F,'\n'); 574 | fprintf(F,'---------------------------------------------------------------------------- \n'); 575 | fprintf(F,'NODE VOLTAGES \n'); 576 | for i=1:num_Nodes 577 | fprintf(F,['v_' num2str(i) ' = ']); 578 | fprintf(F,num2str(eval(eval(['sol.v_' num2str(i)])))); 579 | fprintf(F,'\n'); 580 | end 581 | fprintf(F,'---------------------------------------------------------------------------- \n'); 582 | if(num_V~=0) 583 | fprintf(F,'CURRENTS THROUGH INDEPENDENT VOLTAGE SOURCES (NEGATIVE TO POSITIVE TERMINAL) \n'); 584 | for i=1:num_V 585 | fprintf(F,['i_' Volt_source(i).Name ' = ']); 586 | fprintf(F,num2str(eval(eval(['sol.i_' Volt_source(i).Name])))); 587 | fprintf(F,'\n'); 588 | end 589 | fprintf(F,'---------------------------------------------------------------------------- \n'); 590 | end 591 | if(num_VCVS~=0) 592 | fprintf(F,'CURRENTS THROUGH VOLTAGE CONTROLLED VOLTAGE SOURCES (NEGATIVE TO POSITIVE TERMINAL) \n'); 593 | for i=1:num_VCVS 594 | fprintf(F,['i_' VCVS(i).Name ' = ']); 595 | fprintf(F,num2str(eval(eval(['sol.i_' VCVS(i).Name])))); 596 | fprintf(F,'\n'); 597 | end 598 | fprintf(F,'---------------------------------------------------------------------------- \n'); 599 | end 600 | if(num_CCVS~=0) 601 | fprintf(F,'CURRENTS THROUGH CURRENT CONTROLLED VOLTAGE SOURCES (NEGATIVE TO POSITIVE TERMINAL) \n'); 602 | for i=1:num_CCVS 603 | fprintf(F,['i_' CCVS(i).Name ' = ']); 604 | fprintf(F,num2str(eval(eval(['sol.i_' CCVS(i).Name])))); 605 | fprintf(F,'\n'); 606 | end 607 | fprintf(F,'---------------------------------------------------------------------------- \n'); 608 | end 609 | type('Results.txt'); %Display the contents of Results.txt text file 610 | fclose(F); %Close the Results.txt text file 611 | %%----------------------------------------------------------------------------- 612 | case{1} 613 | %Create the state variables for node voltages, currents through voltage sources and inductor currents 614 | variables='syms'; 615 | for i=1:(num_Nodes+num_V+num_VCVS+num_CCVS+num_L) 616 | variables=[variables ' ' 'v' num2str(i) '(t)']; 617 | end 618 | eval(variables); 619 | %---------------------------------------------- 620 | %Create a row vector var of the state variables - to be used in daeFunction 621 | var_string=['var=[' variables(6:end) ']']; 622 | eval(var_string); 623 | %---------------------------------------------- 624 | %Convert the symbolic equations (only LHS) to a form suitable for daeFunction 625 | %Use the converted symbolic equations to make a row vector eqn_daeFunction - to be used in daeFunction 626 | eqn_string='eqn_daeFunction=['; 627 | for i=1:length(eqn) 628 | interm_string=char(eqn{i}); 629 | for j=1:(num_Nodes+num_V+num_VCVS+num_CCVS+num_L) 630 | interm_string=strrep(interm_string,['v(' num2str(j) ')'],['v' num2str(j) '(t)']); 631 | end 632 | for j=1:num_Nodes 633 | interm_string=strrep(interm_string,['vp(' num2str(j) ')'],['diff(v' num2str(j) ... 634 | '(t)' ',t)']); 635 | end 636 | for j=1:num_L 637 | interm_string=strrep(interm_string,['ip(' num2str(j) ')'],['diff(v' num2str(num_Nodes+num_V+num_VCVS+num_CCVS+j) ... 638 | '(t)' ',t)']); 639 | end 640 | eqn_string=[eqn_string interm_string ',']; 641 | end 642 | eqn_string=[eqn_string ']']; 643 | eval(eqn_string); 644 | %---------------------------------------------- 645 | %Use daeFunction to create the function handle odefun 646 | odefun=daeFunction(eqn_daeFunction,var); 647 | %---------------------------------------------- 648 | %Use ode15i along with created function handle odefun 649 | v0=zeros(length(eqn_daeFunction),1); %Initial conditions for v 650 | vp0=zeros(length(eqn_daeFunction),1); %Initial conditions for v' 651 | disp('----------------------------------------------------------------------------'); 652 | fprintf('The transient analysis will be performed from t=0 to t=tf'); 653 | fprintf('\n'); 654 | tf=input('Enter the final time value tf in seconds : '); 655 | options=odeset('RelTol',1e-03,'AbsTol',1e-03); 656 | [t,v]=ode15i(odefun,[0 tf],v0,vp0,options); 657 | %---------------------------------------------- 658 | table_heading=cell(1,(1+num_Nodes+num_V+num_VCVS+num_CCVS+num_L)); 659 | table_heading{1}='Time'; 660 | for j=1:num_Nodes 661 | table_heading{1+j}=['v_' num2str(j)]; 662 | end 663 | for j=1:num_V 664 | table_heading{1+num_Nodes+j}=['i_' Volt_source(j).Name]; 665 | end 666 | for j=1:num_VCVS 667 | table_heading{1+num_Nodes+num_V+j}=['i_' VCVS(j).Name]; 668 | end 669 | for j=1:num_CCVS 670 | table_heading{1+num_Nodes+num_V+num_VCVS+j}=['i_' CCVS(j).Name]; 671 | end 672 | for j=1:num_L 673 | table_heading{1+num_Nodes+num_V+num_VCVS+num_CCVS+j}=['i_' Inductor(j).Name]; 674 | end 675 | T=array2table([t,v],'VariableNames',table_heading); 676 | date=datetime('now'); 677 | date_string=datestr(date); 678 | xlswrite('Results.xls',{date_string}); 679 | xlswrite('Results.xls',{['File name : ' fname]},1,'A2'); 680 | writetable(T,'Results.xls','Range','A4'); 681 | plot(t,v(:,1:num_Nodes)); %Plot the node voltages vs. time 682 | legend_voltage='legend('; 683 | for i=1:num_Nodes 684 | interm_string=table_heading{1+i}; 685 | interm_string=strrep(interm_string,'_','\_'); 686 | legend_voltage=[legend_voltage '''' interm_string '''' ',']; 687 | end 688 | legend_voltage(end)=')'; 689 | eval(legend_voltage); 690 | xlabel('TIME (s)'); 691 | ylabel('NODE VOLTAGES (V)'); 692 | savefig('Voltages_graph.fig'); 693 | if((num_V~=0)||(num_VCVS~=0)||(num_CCVS~=0)||(num_L~=0)) 694 | figure; %Create new figure window 695 | plot(t,v(:,(num_Nodes+1):end)); %Plot the currents through voltage sources and inductor currents vs. time 696 | legend_current='legend('; 697 | for i=1:num_V 698 | interm_string=table_heading{1+num_Nodes+i}; 699 | interm_string=strrep(interm_string,'_','\_'); 700 | legend_current=[legend_current '''' interm_string '''' ',']; 701 | end 702 | for i=1:num_VCVS 703 | interm_string=table_heading{1+num_Nodes+num_V+i}; 704 | interm_string=strrep(interm_string,'_','\_'); 705 | legend_current=[legend_current '''' interm_string '''' ',']; 706 | end 707 | for i=1:num_CCVS 708 | interm_string=table_heading{1+num_Nodes+num_V+num_VCVS+i}; 709 | interm_string=strrep(interm_string,'_','\_'); 710 | legend_current=[legend_current '''' interm_string '''' ',']; 711 | end 712 | for i=1:num_L 713 | interm_string=table_heading{1+num_Nodes+num_V+num_VCVS+num_CCVS+i}; 714 | interm_string=strrep(interm_string,'_','\_'); 715 | legend_current=[legend_current '''' interm_string '''' ',']; 716 | end 717 | legend_current(end)=')'; 718 | eval(legend_current); 719 | xlabel('TIME (s)'); 720 | ylabel('CURRENTS (A)'); 721 | savefig('Currents_graph.fig'); 722 | end 723 | end -------------------------------------------------------------------------------- /MonteCarlo.m: -------------------------------------------------------------------------------- 1 | %%Delete the results of previous simulation, if any 2 | if(exist('Results.txt')) 3 | delete('Results.txt'); 4 | elseif(exist('Results.xls')) 5 | delete('Results.xls'); 6 | if(exist('MC_values_ode.txt')) 7 | delete('MC_values_ode.txt'); 8 | end 9 | delete('Voltages_graph.fig'); 10 | if(exist('Currents_graph.fig')) 11 | delete('Currents_graph.fig'); 12 | end 13 | end 14 | %%----------------------------------------------------------------------------- 15 | prompt='Enter the file name - '; 16 | fname=input(prompt,'s'); 17 | netlist_fileID=fopen(fname); 18 | netlist=textscan(netlist_fileID,'%s %s %s %s %s %s'); 19 | fclose(netlist_fileID); 20 | runs=input('Enter the number of runs to be performed : '); 21 | disp('----------------------------------------------------------------------------'); 22 | for i_i=1:runs 23 | disp(['RUN ' num2str(i_i)]); 24 | fileID1=fopen('Element_indep.txt','wt+'); %Create an empty text file Element_indep.txt for passive elements and independent sources 25 | fileID2=fopen('VCVS.txt','wt+'); %Create an empty text file VCVS.txt for voltage controlled voltage sources 26 | fileID3=fopen('VCCS.txt','wt+'); %Create an empty text file VCCS.txt for voltage controlled current sources 27 | fileID4=fopen('CCVS.txt','wt+'); %Create an empty text file CCVS.txt for current controlled voltage sources 28 | fileID5=fopen('CCCS.txt','wt+'); %Create an empty text file CCCS.txt for current controlled current sources 29 | %%----------------------------------------------------------------------------- 30 | %%Initialize 31 | num_Elements=0; %Number of passive elements 32 | num_V=0; %Number of independent voltage sources 33 | num_I=0; %Number of independent current sources 34 | num_Nodes=0; %Number of nodes, excluding ground (node 0) 35 | num_VCVS=0; %Number of voltage controlled voltage sources 36 | num_VCCS=0; %Number of voltage controlled current sources 37 | num_CCVS=0; %Number of current controlled voltage sources 38 | num_CCCS=0; %Number of current controlled current sources 39 | num_R=0; %Number of resistors 40 | num_L=0; %Number of inductors 41 | num_C=0; %Number of capacitors 42 | %%----------------------------------------------------------------------------- 43 | for i=1:length(netlist{1}) 44 | s=netlist{1}{i}; 45 | switch(s(1)) 46 | case{'R','L','C','V','I'} %For passive elements and independent sources 47 | fprintf(fileID1,[netlist{1}{i} ' ' netlist{2}{i} ' ' ... 48 | netlist{3}{i} ' ' netlist{4}{i} '\n']); 49 | case{'E'} %For voltage controlled voltage sources 50 | fprintf(fileID2,[netlist{1}{i} ' ' netlist{2}{i} ' ' ... 51 | netlist{3}{i} ' ' netlist{4}{i} ' ' netlist{5}{i} ' ' ... 52 | netlist{6}{i} '\n']); 53 | case{'G'} %For voltage controlled current sources 54 | fprintf(fileID3,[netlist{1}{i} ' ' netlist{2}{i} ' ' ... 55 | netlist{3}{i} ' ' netlist{4}{i} ' ' netlist{5}{i} ' ' ... 56 | netlist{6}{i} '\n']); 57 | case{'H'} %For current controlled voltage sources 58 | fprintf(fileID4,[netlist{1}{i} ' ' netlist{2}{i} ' ' ... 59 | netlist{3}{i} ' ' netlist{4}{i} ' ' netlist{5}{i} '\n']); 60 | case{'F'} %For current controlled current sources 61 | fprintf(fileID5,[netlist{1}{i} ' ' netlist{2}{i} ' ' ... 62 | netlist{3}{i} ' ' netlist{4}{i} ' ' netlist{5}{i} '\n']); 63 | end 64 | end 65 | %%----------------------------------------------------------------------------- 66 | %%Read the data from Element_indep.txt text file 67 | [Name,N1,N2,value]=textread('Element_indep.txt','%s %s %s %s'); 68 | for i=1:length(Name) 69 | switch(Name{i}(1)) 70 | case{'R'} 71 | num_Elements=num_Elements+1; 72 | Element(num_Elements).Name=Name{i}; 73 | Element(num_Elements).Node1=str2num(N1{i}); 74 | Element(num_Elements).Node2=str2num(N2{i}); 75 | Element(num_Elements).Value=str2double(value{i}); 76 | num_R=num_R+1; 77 | if((i_i==1)&&(num_R==1)) %If first run, and first resistor parsed - obtain resistor distribution information from user 78 | dist_R=input('Enter the distribution to be used for resistors :-\n 1. Gaussian (Normal)\n 2. Uniform (Rectangular)\nEnter any other number to keep resistor values fixed at each run\n'); 79 | if dist_R==1 %Normal distribution 80 | SD_R=input('Enter the standard deviation (in %) for resistor Gaussian distribution : '); 81 | elseif dist_R==2 %Uniform distribution 82 | w_R=input('Enter the window size (in %) for resistor Uniform distribution : '); 83 | end 84 | end 85 | if dist_R==1 %Gaussian distribution 86 | if(SD_R>=0) 87 | SD_element = SD_R * Element(num_Elements).Value / 100; 88 | %Create a normal distribution object pd_Element with mean = specified element value, and sigma = specified standard deviation 89 | pd_Element=makedist('Normal','mu',Element(num_Elements).Value,... 90 | 'sigma',SD_element); 91 | r_Element=random(pd_Element); 92 | Element(num_Elements).Value=r_Element; 93 | end 94 | elseif dist_R==2 %Uniform distribution 95 | if(w_R>0) 96 | a = Element(num_Elements).Value - (Element(num_Elements).Value)*w_R/100; 97 | b = Element(num_Elements).Value + (Element(num_Elements).Value)*w_R/100; 98 | %Create a uniform distribution object pd_Element with lower value = a, and upper value = b 99 | pd_Element=makedist('Uniform','lower',a,'upper',b); 100 | r_Element=random(pd_Element); 101 | Element(num_Elements).Value=r_Element; 102 | end 103 | end 104 | case{'C'} 105 | num_Elements=num_Elements+1; 106 | Element(num_Elements).Name=Name{i}; 107 | Element(num_Elements).Node1=str2num(N1{i}); 108 | Element(num_Elements).Node2=str2num(N2{i}); 109 | Element(num_Elements).Value=str2double(value{i}); 110 | num_C=num_C+1; 111 | if((i_i==1)&&(num_C==1)) %If first run, and first capacitor parsed - obtain capacitor distribution information from user 112 | dist_C=input('Enter the distribution to be used for capacitors :-\n 1. Gaussian (Normal)\n 2. Uniform (Rectangular)\nEnter any other number to keep capacitor values fixed at each run\n'); 113 | if dist_C==1 %Normal distribution 114 | SD_C=input('Enter the standard deviation (in %) for capacitor Gaussian distribution : '); 115 | elseif dist_C==2 %Uniform distribution 116 | w_C=input('Enter the window size (in %) for capacitor Uniform distribution : '); 117 | end 118 | end 119 | if dist_C==1 %Gaussian distribution 120 | if(SD_C>=0) 121 | SD_element = SD_C * Element(num_Elements).Value / 100; 122 | %Create a normal distribution object pd_Element with mean = specified element value, and sigma = specified standard deviation 123 | pd_Element=makedist('Normal','mu',Element(num_Elements).Value,... 124 | 'sigma',SD_element); 125 | r_Element=random(pd_Element); 126 | Element(num_Elements).Value=r_Element; 127 | end 128 | elseif dist_C==2 %Uniform distribution 129 | if(w_C>0) 130 | a = Element(num_Elements).Value - (Element(num_Elements).Value)*w_C/100; 131 | b = Element(num_Elements).Value + (Element(num_Elements).Value)*w_C/100; 132 | %Create a uniform distribution object pd_Element with lower value = a, and upper value = b 133 | pd_Element=makedist('Uniform','lower',a,'upper',b); 134 | r_Element=random(pd_Element); 135 | Element(num_Elements).Value=r_Element; 136 | end 137 | end 138 | case{'L'} 139 | num_Elements=num_Elements+1; 140 | Element(num_Elements).Name=Name{i}; 141 | Element(num_Elements).Node1=str2num(N1{i}); 142 | Element(num_Elements).Node2=str2num(N2{i}); 143 | Element(num_Elements).Value=str2double(value{i}); 144 | num_L=num_L+1; 145 | Inductor(num_L).Name=Name{i}; 146 | Inductor(num_L).N1=str2num(N1{i}); 147 | Inductor(num_L).N2=str2num(N2{i}); 148 | Inductor(num_L).Value=str2double(value{i}); 149 | if((i_i==1)&&(num_L==1)) %If first run, and first inductor parsed - obtain inductor distribution information from user 150 | dist_L=input('Enter the distribution to be used for inductors :-\n 1. Gaussian (Normal)\n 2. Uniform (Rectangular)\nEnter any other number to keep inductor values fixed at each run\n'); 151 | if dist_L==1 %Normal distribution 152 | SD_L=input('Enter the standard deviation (in %) for inductor Gaussian distribution : '); 153 | elseif dist_L==2 %Uniform distribution 154 | w_L=input('Enter the window size (in %) for inductor Uniform distribution : '); 155 | end 156 | end 157 | if dist_L==1 %Gaussian distribution 158 | if(SD_L>=0) 159 | SD_element = SD_L * Element(num_Elements).Value / 100; 160 | %Create a normal distribution object pd_Element with mean = specified element value, and sigma = specified standard deviation 161 | pd_Element=makedist('Normal','mu',Element(num_Elements).Value,... 162 | 'sigma',SD_element); 163 | r_Element=random(pd_Element); 164 | Element(num_Elements).Value=r_Element; 165 | Inductor(num_L).Value=r_Element; 166 | end 167 | elseif dist_L==2 %Uniform distribution 168 | if(w_L>0) 169 | a = Element(num_Elements).Value - (Element(num_Elements).Value)*w_L/100; 170 | b = Element(num_Elements).Value + (Element(num_Elements).Value)*w_L/100; 171 | %Create a uniform distribution object pd_Element with lower value = a, and upper value = b 172 | pd_Element=makedist('Uniform','lower',a,'upper',b); 173 | r_Element=random(pd_Element); 174 | Element(num_Elements).Value=r_Element; 175 | Inductor(num_L).Value=r_Element; 176 | end 177 | end 178 | case{'V'} 179 | num_V=num_V+1; 180 | Volt_source(num_V).Name=Name{i}; 181 | Volt_source(num_V).Node1=str2num(N1{i}); 182 | Volt_source(num_V).Node2=str2num(N2{i}); 183 | Volt_source(num_V).Value=str2double(value{i}); 184 | 185 | case{'I'} 186 | num_I=num_I+1; 187 | Current_source(num_I).Name=Name{i}; 188 | Current_source(num_I).Node1=str2num(N1{i}); 189 | Current_source(num_I).Node2=str2num(N2{i}); 190 | Current_source(num_I).Value=str2double(value{i}); 191 | end 192 | num_Nodes=max(str2num(N1{i}),max(str2num(N2{i}),num_Nodes)); 193 | end 194 | %%----------------------------------------------------------------------------- 195 | %%Read the data from VCVS.txt text file 196 | [Name,N1,N2,NC1,NC2,Gain]=textread('VCVS.txt','%s %s %s %s %s %s'); 197 | num_VCVS=length(Name); 198 | for i=1:num_VCVS 199 | VCVS(i).Name=Name{i}; 200 | VCVS(i).N1=str2num(N1{i}); 201 | VCVS(i).N2=str2num(N2{i}); 202 | VCVS(i).NC1=str2num(NC1{i}); 203 | VCVS(i).NC2=str2num(NC2{i}); 204 | VCVS(i).Gain=str2double(Gain{i}); 205 | num_Nodes=max(str2num(N1{i}),max(str2num(N2{i}),num_Nodes)); 206 | end 207 | %%----------------------------------------------------------------------------- 208 | %%Read the data from VCCS.txt text file 209 | [Name,N1,N2,NC1,NC2,Transconductance]=textread('VCCS.txt','%s %s %s %s %s %s'); 210 | num_VCCS=length(Name); 211 | for i=1:num_VCCS 212 | VCCS(i).Name=Name{i}; 213 | VCCS(i).N1=str2num(N1{i}); 214 | VCCS(i).N2=str2num(N2{i}); 215 | VCCS(i).NC1=str2num(NC1{i}); 216 | VCCS(i).NC2=str2num(NC2{i}); 217 | VCCS(i).Transconductance=str2double(Transconductance{i}); 218 | num_Nodes=max(str2num(N1{i}),max(str2num(N2{i}),num_Nodes)); 219 | end 220 | %%----------------------------------------------------------------------------- 221 | %%Read the data from CCVS.txt text file 222 | [Name,N1,N2,Vcontrol,Transresistance]=textread('CCVS.txt','%s %s %s %s %s'); 223 | num_CCVS=length(Name); 224 | for i=1:num_CCVS 225 | CCVS(i).Name=Name{i}; 226 | CCVS(i).N1=str2num(N1{i}); 227 | CCVS(i).N2=str2num(N2{i}); 228 | CCVS(i).Vcontrol=Vcontrol{i}; 229 | CCVS(i).Transresistance=str2double(Transresistance{i}); 230 | num_Nodes=max(str2num(N1{i}),max(str2num(N2{i}),num_Nodes)); 231 | end 232 | %%----------------------------------------------------------------------------- 233 | %%Read the data from CCCS.txt text file 234 | [Name,N1,N2,Vcontrol,Gain]=textread('CCCS.txt','%s %s %s %s %s'); 235 | num_CCCS=length(Name); 236 | for i=1:num_CCCS 237 | CCCS(i).Name=Name{i}; 238 | CCCS(i).N1=str2num(N1{i}); 239 | CCCS(i).N2=str2num(N2{i}); 240 | CCCS(i).Vcontrol=Vcontrol{i}; 241 | CCCS(i).Gain=str2double(Gain{i}); 242 | num_Nodes=max(str2num(N1{i}),max(str2num(N2{i}),num_Nodes)); 243 | end 244 | %%----------------------------------------------------------------------------- 245 | %%Close the no longer required text files and then delete them 246 | fclose(fileID1); 247 | fclose(fileID2); 248 | fclose(fileID3); 249 | fclose(fileID4); 250 | fclose(fileID5); 251 | delete('Element_indep.txt'); 252 | delete('VCVS.txt'); 253 | delete('VCCS.txt'); 254 | delete('CCVS.txt'); 255 | delete('CCCS.txt'); 256 | %%----------------------------------------------------------------------------- 257 | %%Create the equations for the independent voltage sources and apply KCL at the nodes 258 | node_equation=cell(num_Nodes,1); 259 | volt_equation=cell(num_V,1); 260 | for i=1:num_V 261 | switch((Volt_source(i).Node1==0)||(Volt_source(i).Node2==0)) 262 | case{1} 263 | if(Volt_source(i).Node1==0) 264 | volt=['v_' num2str(Volt_source(i).Node2) '=' '-' num2str(Volt_source(i).Value)]; 265 | node_equation{Volt_source(i).Node2}=[node_equation{Volt_source(i).Node2} ... 266 | '-' 'i_' Volt_source(i).Name]; 267 | else 268 | volt=['v_' num2str(Volt_source(i).Node1) '=' num2str(Volt_source(i).Value)]; 269 | node_equation{Volt_source(i).Node1}=[node_equation{Volt_source(i).Node1} ... 270 | '+' 'i_' Volt_source(i).Name]; 271 | end 272 | volt_equation{i}=volt; 273 | case{0} 274 | volt=['v_' num2str(Volt_source(i).Node1) '-' ... 275 | 'v_' num2str(Volt_source(i).Node2) '=' num2str(Volt_source(i).Value)]; 276 | volt_equation{i}=volt; 277 | node_equation{Volt_source(i).Node1}=[node_equation{Volt_source(i).Node1} ... 278 | '+' 'i_' Volt_source(i).Name]; 279 | node_equation{Volt_source(i).Node2}=[node_equation{Volt_source(i).Node2} ... 280 | '-' 'i_' Volt_source(i).Name]; 281 | end 282 | end 283 | %%----------------------------------------------------------------------------- 284 | %%Create the equations for the voltage controlled voltage sources and apply KCL at the nodes 285 | VCVS_equation=cell(num_VCVS,1); 286 | for i=1:num_VCVS 287 | switch((VCVS(i).N1==0)||(VCVS(i).N2==0)) 288 | case{1} 289 | if(VCVS(i).N1==0) 290 | switch((VCVS(i).NC1==0)||(VCVS(i).NC2==0)) 291 | case{1} 292 | if(VCVS(i).NC1==0) 293 | volt=['-' 'v_' num2str(VCVS(i).N2) '-' num2str(VCVS(i).Gain) ... 294 | '*' '(' '-' 'v_' num2str(VCVS(i).NC2) ')']; 295 | else 296 | volt=['-' 'v_' num2str(VCVS(i).N2) '-' num2str(VCVS(i).Gain) ... 297 | '*' '(' 'v_' num2str(VCVS(i).NC1) ')']; 298 | end 299 | case{0} 300 | volt=['-' 'v_' num2str(VCVS(i).N2) '-' num2str(VCVS(i).Gain) ... 301 | '*' '(' 'v_' num2str(VCVS(i).NC1) '-' 'v_' num2str(VCVS(i).NC2) ')']; 302 | end 303 | node_equation{VCVS(i).N2}=[node_equation{VCVS(i).N2} '-' 'i_' VCVS(i).Name]; 304 | else 305 | switch((VCVS(i).NC1==0)||(VCVS(i).NC2==0)) 306 | case{1} 307 | if(VCVS(i).NC1==0) 308 | volt=['v_' num2str(VCVS(i).N1) '-' num2str(VCVS(i).Gain) ... 309 | '*' '(' '-' 'v_' num2str(VCVS(i).NC2) ')']; 310 | else 311 | volt=['v_' num2str(VCVS(i).N1) '-' num2str(VCVS(i).Gain) ... 312 | '*' '(' 'v_' num2str(VCVS(i).NC1) ')']; 313 | end 314 | case{0} 315 | volt=['v_' num2str(VCVS(i).N1) '-' num2str(VCVS(i).Gain) ... 316 | '*' '(' 'v_' num2str(VCVS(i).NC1) '-' 'v_' num2str(VCVS(i).NC2) ')']; 317 | end 318 | node_equation{VCVS(i).N1}=[node_equation{VCVS(i).N1} '+' 'i_' VCVS(i).Name]; 319 | end 320 | case{0} 321 | switch((VCVS(i).NC1==0)||(VCVS(i).NC2==0)) 322 | case{1} 323 | if(VCVS(i).NC1==0) 324 | volt=['v_' num2str(VCVS(i).N1) '-' 'v_' num2str(VCVS(i).N2) '-' ... 325 | num2str(VCVS(i).Gain) '*' '(' '-' 'v_' num2str(VCVS(i).NC2) ')']; 326 | else 327 | volt=['v_' num2str(VCVS(i).N1) '-' 'v_' num2str(VCVS(i).N2) '-' ... 328 | num2str(VCVS(i).Gain) '*' '(' 'v_' num2str(VCVS(i).NC1) ')']; 329 | end 330 | case{0} 331 | volt=['v_' num2str(VCVS(i).N1) '-' 'v_' num2str(VCVS(i).N2) '-' ... 332 | num2str(VCVS(i).Gain) '*' '(' 'v_' num2str(VCVS(i).NC1) '-' 'v_' num2str(VCVS(i).NC2) ')']; 333 | end 334 | node_equation{VCVS(i).N1}=[node_equation{VCVS(i).N1} '+' 'i_' VCVS(i).Name]; 335 | node_equation{VCVS(i).N2}=[node_equation{VCVS(i).N2} '-' 'i_' VCVS(i).Name]; 336 | end 337 | VCVS_equation{i}=volt; 338 | end 339 | %%----------------------------------------------------------------------------- 340 | %%Create the equations for the current controlled voltage sources and apply KCL at the nodes 341 | CCVS_equation=cell(num_CCVS,1); 342 | for i=1:num_CCVS 343 | switch((CCVS(i).N1==0)||(CCVS(i).N2==0)) 344 | case{1} 345 | if(CCVS(i).N1==0) 346 | volt=['v_' num2str(CCVS(i).N2) '+' '(' num2str(CCVS(i).Transresistance) '*' 'i_' CCVS(i).Vcontrol ')']; 347 | node_equation{CCVS(i).N2}=[node_equation{CCVS(i).N2} ... 348 | '-' 'i_' CCVS(i).Name]; 349 | else 350 | volt=['v_' num2str(CCVS(i).N1) '-' '(' num2str(CCVS(i).Transresistance) '*' 'i_' CCVS(i).Vcontrol ')']; 351 | node_equation{CCVS(i).N1}=[node_equation{CCVS(i).N1} ... 352 | '+' 'i_' CCVS(i).Name]; 353 | end 354 | CCVS_equation{i}=volt; 355 | case{0} 356 | volt=['v_' num2str(CCVS(i).N1) '-' ... 357 | 'v_' num2str(CCVS(i).N2) '-' '(' num2str(CCVS(i).Transresistance) '*' 'i_' CCVS(i).Vcontrol ')']; 358 | CCVS_equation{i}=volt; 359 | node_equation{CCVS(i).N1}=[node_equation{CCVS(i).N1} ... 360 | '+' 'i_' CCVS(i).Name]; 361 | node_equation{CCVS(i).N2}=[node_equation{CCVS(i).N2} ... 362 | '-' 'i_' CCVS(i).Name]; 363 | end 364 | end 365 | %%----------------------------------------------------------------------------- 366 | solver_flag=0; %A flag used for deciding which solver to finally use 367 | %solver_flag=0 => Purely resistive circuit, use solve for the equations 368 | %solver_flag=1 => Pure C, pure L, LC, RC, RL or RLC circuit, use ode15i for the equations 369 | %%----------------------------------------------------------------------------- 370 | %%Add the passive element currents using KCL to the node equations, and make the equations for inductors 371 | L_equation=cell(num_L,1); 372 | L_ctr=0; 373 | for i=1:num_Elements 374 | switch(Element(i).Name(1)) 375 | case{'R'} 376 | switch((Element(i).Node1==0)||(Element(i).Node2==0)) 377 | case{0} 378 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} '+' '(' ... 379 | 'v_' num2str(Element(i).Node2) '-' 'v_' ... 380 | num2str(Element(i).Node1) ')' '/' num2str(Element(i).Value)]; 381 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} '+' '(' ... 382 | 'v_' num2str(Element(i).Node1) '-' 'v_' ... 383 | num2str(Element(i).Node2) ')' '/' num2str(Element(i).Value)]; 384 | case{1} 385 | if(Element(i).Node1==0) 386 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} ... 387 | '-' '(' 'v_' num2str(Element(i).Node2) ')' '/' num2str(Element(i).Value)]; 388 | else 389 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} ... 390 | '-' '(' 'v_' num2str(Element(i).Node1) ')' '/' num2str(Element(i).Value)]; 391 | end 392 | end 393 | case{'C'} 394 | if(solver_flag==0) 395 | solver_flag=1; 396 | end 397 | switch((Element(i).Node1==0)||(Element(i).Node2==0)) 398 | case{0} 399 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} ... 400 | '+' num2str(Element(i).Value) '*' '(' 'vp(' num2str(Element(i).Node2) ')' ... 401 | '-' 'vp(' num2str(Element(i).Node1) ')' ')']; 402 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} ... 403 | '+' num2str(Element(i).Value) '*' '(' 'vp(' num2str(Element(i).Node1) ')' ... 404 | '-' 'vp(' num2str(Element(i).Node2) ')' ')']; 405 | case{1} 406 | if(Element(i).Node1==0) 407 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} ... 408 | '-' num2str(Element(i).Value) '*' '(' 'vp(' num2str(Element(i).Node2) ')' ')']; 409 | else 410 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} ... 411 | '-' num2str(Element(i).Value) '*' '(' 'vp(' num2str(Element(i).Node1) ')' ')']; 412 | end 413 | end 414 | case{'L'} 415 | if(solver_flag==0) 416 | solver_flag=1; 417 | end 418 | L_ctr=L_ctr+1; 419 | switch((Element(i).Node1==0)||(Element(i).Node2==0)) 420 | case{0} 421 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} '-' 'i_' Element(i).Name]; 422 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} '+' 'i_' Element(i).Name]; 423 | L_equation{L_ctr}=['v_' num2str(Element(i).Node1) '-' 'v_' num2str(Element(i).Node2) '-' ... 424 | '(' num2str(Element(i).Value) '*' 'ip(' num2str(L_ctr) ')' ')']; 425 | case{1} 426 | if(Element(i).Node1==0) 427 | node_equation{Element(i).Node2}=[node_equation{Element(i).Node2} '+' 'i_' Element(i).Name]; 428 | L_equation{L_ctr}=['-' 'v_' num2str(Element(i).Node2) '-' ... 429 | '(' num2str(Element(i).Value) '*' 'ip(' num2str(L_ctr) ')' ')']; 430 | else 431 | node_equation{Element(i).Node1}=[node_equation{Element(i).Node1} '-' 'i_' Element(i).Name]; 432 | L_equation{L_ctr}=['v_' num2str(Element(i).Node1) '-' ... 433 | '(' num2str(Element(i).Value) '*' 'ip(' num2str(L_ctr) ')' ')']; 434 | end 435 | end 436 | end 437 | end 438 | %%----------------------------------------------------------------------------- 439 | %%Add the independent current sources using KCL to the node equations 440 | for i=1:num_I 441 | switch((Current_source(i).Node1==0)||(Current_source(i).Node2==0)) 442 | case{1} 443 | if(Current_source(i).Node1==0) 444 | node_equation{Current_source(i).Node2}=[node_equation{Current_source(i).Node2} ... 445 | '+' num2str(Current_source(i).Value)]; 446 | else 447 | node_equation{Current_source(i).Node1}=[node_equation{Current_source(i).Node1} ... 448 | '-' num2str(Current_source(i).Value)]; 449 | end 450 | case{0} 451 | node_equation{Current_source(i).Node1}=[node_equation{Current_source(i).Node1} ... 452 | '-' num2str(Current_source(i).Value)]; 453 | node_equation{Current_source(i).Node2}=[node_equation{Current_source(i).Node2} ... 454 | '+' num2str(Current_source(i).Value)]; 455 | end 456 | end 457 | %%----------------------------------------------------------------------------- 458 | %%Next, add the voltage controlled current sources using KCL to the node equations 459 | for i=1:num_VCCS 460 | switch((VCCS(i).N1==0)||(VCCS(i).N2==0)) 461 | case{1} 462 | if(VCCS(i).N1==0) 463 | switch((VCCS(i).NC1==0)||(VCCS(i).NC2==0)) 464 | case{1} 465 | if(VCCS(i).NC1==0) 466 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 467 | num2str(VCCS(i).Transconductance) '*' '(' '-' 'v_' num2str(VCCS(i).NC2) ')']; 468 | else 469 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 470 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) ')']; 471 | end 472 | case{0} 473 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 474 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) '-' ... 475 | 'v_' num2str(VCCS(i).NC2) ')']; 476 | end 477 | else 478 | switch((VCCS(i).NC1==0)||(VCCS(i).NC2==0)) 479 | case{1} 480 | if(VCCS(i).NC1==0) 481 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 482 | num2str(VCCS(i).Transconductance) '*' '(' '-' 'v_' num2str(VCCS(i).NC2) ')']; 483 | else 484 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 485 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) ')']; 486 | end 487 | case{0} 488 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 489 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) ... 490 | '-' 'v_' num2str(VCCS(i).NC2) ')']; 491 | end 492 | end 493 | case{0} 494 | switch((VCCS(i).NC1==0)||(VCCS(i).NC2==0)) 495 | case{1} 496 | if(VCCS(i).NC1==0) 497 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 498 | num2str(VCCS(i).Transconductance) '*' '(' '-' 'v_' num2str(VCCS(i).NC2) ')']; 499 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 500 | num2str(VCCS(i).Transconductance) '*' '(' '-' 'v_' num2str(VCCS(i).NC2) ')']; 501 | else 502 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 503 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) ')']; 504 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 505 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) ')']; 506 | end 507 | case{0} 508 | node_equation{VCCS(i).N1}=[node_equation{VCCS(i).N1} '-' ... 509 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) '-' ... 510 | 'v_' num2str(VCCS(i).NC2) ')']; 511 | node_equation{VCCS(i).N2}=[node_equation{VCCS(i).N2} '+' ... 512 | num2str(VCCS(i).Transconductance) '*' '(' 'v_' num2str(VCCS(i).NC1) '-' ... 513 | 'v_' num2str(VCCS(i).NC2) ')']; 514 | end 515 | end 516 | end 517 | %%----------------------------------------------------------------------------- 518 | %%Finally, add the current controlled current sources using KCL to the node equations 519 | for i=1:num_CCCS 520 | switch((CCCS(i).N1==0)||(CCCS(i).N2==0)) 521 | case{1} 522 | if(CCCS(i).N1==0) 523 | node_equation{CCCS(i).N2}=[node_equation{CCCS(i).N2} ... 524 | '+' '(' num2str(CCCS(i).Gain) '*' 'i_' CCCS(i).Vcontrol ')']; 525 | else 526 | node_equation{CCCS(i).N1}=[node_equation{CCCS(i).N1} ... 527 | '-' '(' num2str(CCCS(i).Gain) '*' 'i_' CCCS(i).Vcontrol ')']; 528 | end 529 | case{0} 530 | node_equation{CCCS(i).N1}=[node_equation{CCCS(i).N1} ... 531 | '-' '(' num2str(CCCS(i).Gain) '*' 'i_' CCCS(i).Vcontrol ')']; 532 | node_equation{CCCS(i).N2}=[node_equation{CCCS(i).N2} ... 533 | '+' '(' num2str(CCCS(i).Gain) '*' 'i_' CCCS(i).Vcontrol ')']; 534 | end 535 | end 536 | %%----------------------------------------------------------------------------- 537 | %%If solver_flag=0 (purely resistive circuit), add the RHS('=0') to each 538 | %%nodal KCL equation, to each VCVS equation, and to each CCVS equation 539 | if(solver_flag==0) 540 | for i=1:length(node_equation) 541 | node_equation{i}=[node_equation{i} '=' '0']; 542 | end 543 | for i=1:length(VCVS_equation) 544 | VCVS_equation{i}=[VCVS_equation{i} '=' '0']; 545 | end 546 | for i=1:length(CCVS_equation) 547 | CCVS_equation{i}=[CCVS_equation{i} '=' '0']; 548 | end 549 | %%Else if solver_flag=1 (Pure C, pure L, LC, RC, RL or RLC circuit), do NOT add the RHS ('=0') 550 | %%to each nodal KCL equation, to each VCVS equation, to each CCVS equation and to each inductor equation, instead replace 551 | %%the node voltage terms v_1,v_2,...v_num_Nodes in LHS of all the equations with v(1),v(2),...v(num_Nodes) respectively, 552 | %%modify each independent voltage source equation to only LHS [no RHS ('=0')] (similar to all the other equations), 553 | %%also replace the independent voltage source current terms with v(num_Nodes+j) (j=1:num_V) 554 | %%VCVS current terms with v(num_Nodes+num_V+j) (j=1:num_VCVS) 555 | %%CCVS current terms with v(num_Nodes+num_V+num_VCVS+j) (j=1:num_CCVS) 556 | %%and inductor current terms with v(num_Nodes+num_V+num_VCVS+num_CCVS+j) (j=1:num_L) 557 | elseif(solver_flag==1) 558 | for i=1:num_Nodes %For each nodal KCL equation (only LHS) 559 | for j=1:num_Nodes 560 | node_equation{i}=strrep(node_equation{i},['v_' num2str(j)],['v(' num2str(j) ')']); 561 | end 562 | for j=1:num_V 563 | node_equation{i}=strrep(node_equation{i},['i_' Volt_source(j).Name],['v(' num2str(num_Nodes+j) ')']); 564 | end 565 | for j=1:num_VCVS 566 | node_equation{i}=strrep(node_equation{i},['i_' VCVS(j).Name],['v(' num2str(num_Nodes+num_V+j) ')']); 567 | end 568 | for j=1:num_CCVS 569 | node_equation{i}=strrep(node_equation{i},['i_' CCVS(j).Name],['v(' num2str(num_Nodes+num_V+num_VCVS+j) ')']); 570 | end 571 | for j=1:num_L 572 | node_equation{i}=strrep(node_equation{i},['i_' Inductor(j).Name],['v(' num2str(num_Nodes+num_V+num_VCVS+num_CCVS+j) ')']); 573 | end 574 | end 575 | for i=1:num_V %For each independent voltage source equation 576 | for j=1:num_Nodes 577 | volt_equation{i}=strrep(volt_equation{i},['v_' num2str(j)],['v(' num2str(j) ')']); 578 | end 579 | volt_equation{i}=strrep(volt_equation{i},'=','-'); %Modify each independent voltage source equation to only LHS [no RHS ('=0')] 580 | end 581 | for i=1:num_VCVS %For each VCVS equation (only LHS) 582 | for j=1:num_Nodes 583 | VCVS_equation{i}=strrep(VCVS_equation{i},['v_' num2str(j)],['v(' num2str(j) ')']); 584 | end 585 | end 586 | for i=1:num_CCVS %For each CCVS equation (only LHS) 587 | for j=1:num_Nodes 588 | CCVS_equation{i}=strrep(CCVS_equation{i},['v_' num2str(j)],['v(' num2str(j) ')']); 589 | end 590 | for j=1:num_V 591 | CCVS_equation{i}=strrep(CCVS_equation{i},['i_' Volt_source(j).Name],['v(' num2str(num_Nodes+j) ')']); 592 | end 593 | for j=1:num_VCVS 594 | CCVS_equation{i}=strrep(CCVS_equation{i},['i_' VCVS(j).Name],['v(' num2str(num_Nodes+num_V+j) ')']); 595 | end 596 | for j=1:num_CCVS 597 | CCVS_equation{i}=strrep(CCVS_equation{i},['i_' CCVS(j).Name],['v(' num2str(num_Nodes+num_V+num_VCVS+j) ')']); 598 | end 599 | end 600 | for i=1:num_L %For each inductor equation (only LHS) 601 | for j=1:num_Nodes 602 | L_equation{i}=strrep(L_equation{i},['v_' num2str(j)],['v(' num2str(j) ')']); 603 | end 604 | end 605 | end 606 | %%----------------------------------------------------------------------------- 607 | eqn=cell(num_Nodes+num_V+num_VCVS+num_CCVS+num_L,1); 608 | for i=1:num_Nodes 609 | eqn{i}=evalin(symengine,node_equation{i}); 610 | end 611 | for i=1:num_V 612 | eqn{num_Nodes+i}=evalin(symengine,volt_equation{i}); 613 | end 614 | for i=1:num_VCVS 615 | eqn{num_Nodes+num_V+i}=evalin(symengine,VCVS_equation{i}); 616 | end 617 | for i=1:num_CCVS 618 | eqn{num_Nodes+num_V+num_VCVS+i}=evalin(symengine,CCVS_equation{i}); 619 | end 620 | for i=1:num_L 621 | eqn{num_Nodes+num_V+num_VCVS+num_CCVS+i}=evalin(symengine,L_equation{i}); 622 | end 623 | %%----------------------------------------------------------------------------- 624 | switch(solver_flag) 625 | case{0} 626 | if(i_i==1) %If first run 627 | %Create the symbolic variables for node voltages and currents through voltage sources 628 | variables='syms'; 629 | for i=1:num_Nodes 630 | variables=[variables ' ' 'v_' num2str(i)]; 631 | end 632 | for i=1:num_V 633 | variables=[variables ' ' 'i_' Volt_source(i).Name]; 634 | end 635 | for i=1:num_VCVS 636 | variables=[variables ' ' 'i_' VCVS(i).Name]; 637 | end 638 | for i=1:num_CCVS 639 | variables=[variables ' ' 'i_' CCVS(i).Name]; 640 | end 641 | eval(variables); 642 | %---------------------------------------------- 643 | %Create a row vector var of the symbolic variables created above - to be used in solve at each run 644 | var_string=['var=[' variables(6:end) ']']; 645 | eval(var_string); 646 | %---------------------------------------------- 647 | %Create the symbolic variables for the symbolic equations 648 | equations='syms'; 649 | for i=1:(num_Nodes+num_V+num_VCVS+num_CCVS) 650 | equations=[equations ' ' 'eqn' num2str(i)]; 651 | end 652 | eval(equations); 653 | %---------------------------------------------- 654 | %Create a row vector eqn_solve of the equation symbolic variables 655 | interm_string=['eqn_solve=[' equations(6:end) ']']; 656 | eval(interm_string); 657 | end 658 | %---------------------------------------------- 659 | %Assign the equation symbolic variables with the corresponding symbolic equations 660 | for i=1:(num_Nodes+num_V+num_VCVS+num_CCVS) 661 | eqn_string=['eqn' num2str(i) '=' 'eqn{' num2str(i) '}']; 662 | eval(eqn_string); 663 | end 664 | %---------------------------------------------- 665 | %Solve the symbolic linear equations using solve 666 | sol=solve(eval(eqn_solve),var); 667 | %Note :- We use eval(eqn_solve) to substitute the symbolic equation associated with 668 | %each equation symbolic variable 669 | %---------------------------------------------- 670 | if(i_i==1) %If first run 671 | F=fopen('Results.txt','wt+'); %Create an empty text file Results.txt 672 | date=datetime('now'); 673 | date_string=datestr(date); 674 | fprintf(F,date_string); 675 | fprintf(F,'\n'); 676 | fprintf(F,['File name : ' fname]); 677 | fprintf(F,'\n'); 678 | if(dist_R==1) 679 | fprintf(F,'Resistor Distribution : Normal'); 680 | fprintf(F,'\n'); 681 | fprintf(F,['Resistor Standard deviation in %% : ' num2str(SD_R)]); 682 | fprintf(F,'\n'); 683 | elseif(dist_R==2) 684 | fprintf(F,'Resistor Distribution : Uniform'); 685 | fprintf(F,'\n'); 686 | fprintf(F,['Resistor Window size in %% : ' num2str(w_R)]); 687 | fprintf(F,'\n'); 688 | else 689 | fprintf(F,'Resistor Distribution : None'); 690 | fprintf(F,'\n'); 691 | end 692 | fprintf(F,['Number of runs : ' num2str(runs)]); 693 | fprintf(F,'\n'); 694 | fprintf(F,'---------------------------------------------------------------------------- \n'); 695 | end 696 | fprintf(F,['RUN ' num2str(i_i)]); 697 | fprintf(F,'\n \n'); 698 | it = 1; 699 | for j=1:num_Elements 700 | fprintf(F,Element(j).Name); 701 | fprintf(F,' = '); 702 | fprintf(F,[num2str(Element(j).Value) '\n']); 703 | end 704 | fprintf(F,'---------------------------------------------------------------------------- \n'); 705 | fprintf(F,'NODE VOLTAGES \n'); 706 | for i=1:num_Nodes 707 | fprintf(F,['v_' num2str(i) ' = ']); 708 | fprintf(F,num2str(eval(eval(['sol.v_' num2str(i)])))); 709 | fprintf(F,'\n'); 710 | table(i_i, it) = eval(eval(['sol.v_' num2str(i)])); 711 | it = it + 1; 712 | end 713 | fprintf(F,'---------------------------------------------------------------------------- \n'); 714 | if(num_V~=0) 715 | fprintf(F,'CURRENTS THROUGH INDEPENDENT VOLTAGE SOURCES (NEGATIVE TO POSITIVE TERMINAL) \n'); 716 | for i=1:num_V 717 | fprintf(F,['i_' Volt_source(i).Name ' = ']); 718 | fprintf(F,num2str(eval(eval(['sol.i_' Volt_source(i).Name])))); 719 | fprintf(F,'\n'); 720 | table(i_i, it) = eval(eval(['sol.i_' Volt_source(i).Name])); 721 | it = it + 1; 722 | end 723 | fprintf(F,'---------------------------------------------------------------------------- \n'); 724 | end 725 | if(num_VCVS~=0) 726 | fprintf(F,'CURRENTS THROUGH VOLTAGE CONTROLLED VOLTAGE SOURCES (NEGATIVE TO POSITIVE TERMINAL) \n'); 727 | for i=1:num_VCVS 728 | fprintf(F,['i_' VCVS(i).Name ' = ']); 729 | fprintf(F,num2str(eval(eval(['sol.i_' VCVS(i).Name])))); 730 | fprintf(F,'\n'); 731 | table(i_i, it) = eval(eval(['sol.i_' VCVS(i).Name])); 732 | it = it + 1; 733 | end 734 | fprintf(F,'---------------------------------------------------------------------------- \n'); 735 | end 736 | if(num_CCVS~=0) 737 | fprintf(F,'CURRENTS THROUGH CURRENT CONTROLLED VOLTAGE SOURCES (NEGATIVE TO POSITIVE TERMINAL) \n'); 738 | for i=1:num_CCVS 739 | fprintf(F,['i_' CCVS(i).Name ' = ']); 740 | fprintf(F,num2str(eval(eval(['sol.i_' CCVS(i).Name])))); 741 | fprintf(F,'\n'); 742 | table(i_i, it) = eval(eval(['sol.i_' CCVS(i).Name])); 743 | it = it + 1; 744 | end 745 | fprintf(F,'---------------------------------------------------------------------------- \n'); 746 | end 747 | if(i_i==runs) %If last run 748 | type('Results.txt'); %Display the contents of Results.txt text file 749 | fclose(F); %Close the Results.txt text file 750 | [m,n] = size(table); 751 | x = 1:m; 752 | for i=1:num_Nodes %Plot each node voltage recorded at each run 753 | figure; 754 | quant = table(:,i); 755 | stem(x,quant); 756 | xlabel('RUN'); 757 | ylabel(['v\_' num2str(i) ' (V)']); 758 | end 759 | for i=1:num_V %Plot each independent voltage source current recorded at each run 760 | figure; 761 | quant = table(:,(num_Nodes+i)); 762 | stem(x,quant); 763 | xlabel('RUN'); 764 | ylabel(['i\_' Volt_source(i).Name ' (A)']); 765 | end 766 | for i=1:num_VCVS %Plot each VCVS current recorded at each run 767 | figure; 768 | quant = table(:,(num_Nodes+num_V+i)); 769 | stem(x,quant); 770 | xlabel('RUN'); 771 | ylabel(['i\_' VCVS(i).Name ' (A)']); 772 | end 773 | for i=1:num_CCVS %Plot each CCVS current recorded at each run 774 | figure; 775 | quant = table(:,(num_Nodes+num_V+num_VCVS+i)); 776 | stem(x,quant); 777 | xlabel('RUN'); 778 | ylabel(['i\_' CCVS(i).Name ' (A)']); 779 | end 780 | end 781 | %%----------------------------------------------------------------------------- 782 | case{1} 783 | %Create the state variables for node voltages, currents through voltage sources and inductor currents 784 | variables='syms'; 785 | for i=1:(num_Nodes+num_V+num_VCVS+num_CCVS+num_L) 786 | variables=[variables ' ' 'v' num2str(i) '(t)']; 787 | end 788 | eval(variables); 789 | %---------------------------------------------- 790 | %Create a row vector var of the state variables - to be used in daeFunction 791 | var_string=['var=[' variables(6:end) ']']; 792 | eval(var_string); 793 | %---------------------------------------------- 794 | %Convert the symbolic equations (only LHS) to a form suitable for daeFunction 795 | %Use the converted symbolic equations to make a row vector eqn_daeFunction - to be used in daeFunction 796 | eqn_string='eqn_daeFunction=['; 797 | for i=1:length(eqn) 798 | interm_string=char(eqn{i}); 799 | for j=1:(num_Nodes+num_V+num_VCVS+num_CCVS+num_L) 800 | interm_string=strrep(interm_string,['v(' num2str(j) ')'],['v' num2str(j) '(t)']); 801 | end 802 | for j=1:num_Nodes 803 | interm_string=strrep(interm_string,['vp(' num2str(j) ')'],['diff(v' num2str(j) ... 804 | '(t)' ',t)']); 805 | end 806 | for j=1:num_L 807 | interm_string=strrep(interm_string,['ip(' num2str(j) ')'],['diff(v' num2str(num_Nodes+num_V+num_VCVS+num_CCVS+j) ... 808 | '(t)' ',t)']); 809 | end 810 | eqn_string=[eqn_string interm_string ',']; 811 | end 812 | eqn_string=[eqn_string ']']; 813 | eval(eqn_string); 814 | %---------------------------------------------- 815 | %Use daeFunction to create the function handle odefun 816 | odefun=daeFunction(eqn_daeFunction,var); 817 | %---------------------------------------------- 818 | %Use ode15i along with created function handle odefun 819 | v0=zeros(length(eqn_daeFunction),1); %Initial conditions for v 820 | vp0=zeros(length(eqn_daeFunction),1); %Initial conditions for v' 821 | if(i_i==1) %If first run, obtain the simulation time tf for each run from the user 822 | fprintf('The transient analysis at each run will be performed from t=0 to t=tf'); 823 | fprintf('\n'); 824 | tf=input('Enter the final time value tf in seconds : '); 825 | end 826 | options=odeset('RelTol',1e-03,'AbsTol',1e-03); 827 | [t,v]=ode15i(odefun,[0 tf],v0,vp0,options); 828 | %---------------------------------------------- 829 | if(i_i==1) %If first run 830 | G=fopen('MC_values_ode.txt','wt+'); %Create an empty text file MC_values_ode.txt 831 | end 832 | fprintf(G,['RUN ' num2str(i_i)]); 833 | fprintf(G,'\n \n'); 834 | for j=1:num_Elements 835 | fprintf(G,[Element(j).Name ' = ' num2str(Element(j).Value)]); 836 | fprintf(G,'\n'); 837 | end 838 | fprintf(G,'---------------------------------------------------------------------------- \n'); 839 | if(i_i==1) 840 | table_heading=cell(1,(1+num_Nodes+num_V+num_VCVS)); 841 | table_heading{1}='Time'; 842 | for j=1:num_Nodes 843 | table_heading{1+j}=['v_' num2str(j)]; 844 | end 845 | for j=1:num_V 846 | table_heading{1+num_Nodes+j}=['i_' Volt_source(j).Name]; 847 | end 848 | for j=1:num_VCVS 849 | table_heading{1+num_Nodes+num_V+j}=['i_' VCVS(j).Name]; 850 | end 851 | for j=1:num_CCVS 852 | table_heading{1+num_Nodes+num_V+num_VCVS+j}=['i_' CCVS(j).Name]; 853 | end 854 | for j=1:num_L 855 | table_heading{1+num_Nodes+num_V+num_VCVS+num_CCVS+j}=['i_' Inductor(j).Name]; 856 | end 857 | end 858 | T=array2table([t,v],'VariableNames',table_heading); 859 | if(i_i==1) %If first run 860 | orig_state=warning('query','MATLAB:xlswrite:AddSheet'); %Save the current state of warning 'MATLAB:xlswrite:AddSheet' in structure array orig_state 861 | warning('off','MATLAB:xlswrite:AddSheet'); %Turn off 'MATLAB:xlswrite:AddSheet' warning 862 | date=datetime('now'); 863 | date_string=datestr(date); 864 | xlswrite('Results.xls',{date_string}); 865 | xlswrite('Results.xls',{['File name : ' fname]},1,'A2'); 866 | if(num_R~=0) 867 | if(dist_R==1) 868 | xlswrite('Results.xls',{'Resistor Distribution : Normal'},1,'A3'); 869 | xlswrite('Results.xls',{['Resistor SD in % : ' num2str(SD_R)]},1,'A4'); 870 | elseif(dist_R==2) 871 | xlswrite('Results.xls',{'Resistor Distribution : Uniform'},1,'A3'); 872 | xlswrite('Results.xls',{['Resistor Window size % : ' num2str(w_R)]},1,'A4'); 873 | else 874 | xlswrite('Results.xls',{'Resistor Distribution : None'},1,'A3'); 875 | end 876 | end 877 | if(num_C~=0) 878 | if(dist_C==1) 879 | xlswrite('Results.xls',{'Capacitor Distribution : Normal'},1,'A5'); 880 | xlswrite('Results.xls',{['Capacitor SD in % : ' num2str(SD_C)]},1,'A6'); 881 | elseif(dist_C==2) 882 | xlswrite('Results.xls',{'Capacitor Distribution : Uniform'},1,'A5'); 883 | xlswrite('Results.xls',{['Capacitor Window size % : ' num2str(w_C)]},1,'A6'); 884 | else 885 | xlswrite('Results.xls',{'Capacitor Distribution : None'},1,'A5'); 886 | end 887 | end 888 | if(num_L~=0) 889 | if(dist_L==1) 890 | xlswrite('Results.xls',{'Inductor Distribution : Normal'},1,'A7'); 891 | xlswrite('Results.xls',{['Inductor SD in % : ' num2str(SD_L)]},1,'A8'); 892 | elseif(dist_L==2) 893 | xlswrite('Results.xls',{'Inductor Distribution : Uniform'},1,'A7'); 894 | xlswrite('Results.xls',{['Inductor Window size % : ' num2str(w_L)]},1,'A8'); 895 | else 896 | xlswrite('Results.xls',{'Inductor Distribution : None'},1,'A7'); 897 | end 898 | end 899 | xlswrite('Results.xls',{['Runs : ' num2str(runs)]},1,'A9'); 900 | end 901 | writetable(T,'Results.xls','Range','A11','Sheet',i_i); 902 | figure(1); 903 | plot(t,v(:,1:num_Nodes));hold on; %Plot the node voltages vs. time 904 | if(i_i==1) 905 | legend_voltage='legend('; 906 | end 907 | for i=1:num_Nodes 908 | interm_string=table_heading{1+i}; 909 | interm_string=strrep(interm_string,'_','\_'); 910 | legend_voltage=[legend_voltage '''' interm_string ' (RUN ' num2str(i_i) ')' '''' ',']; 911 | end 912 | if(i_i==runs) 913 | legend_voltage(end)=')'; 914 | eval(legend_voltage); 915 | xlabel('TIME (s)'); 916 | ylabel('NODE VOLTAGES (V)'); 917 | end 918 | if((num_V~=0)||(num_VCVS~=0)||(num_CCVS~=0)||(num_L~=0)) 919 | figure(2); 920 | plot(t,v(:,(num_Nodes+1):end));hold on; %Plot the currents through voltage sources and inductor currents vs. time 921 | if(i_i==1) 922 | legend_current='legend('; 923 | end 924 | for i=1:num_V 925 | interm_string=table_heading{1+num_Nodes+i}; 926 | interm_string=strrep(interm_string,'_','\_'); 927 | legend_current=[legend_current '''' interm_string ' (RUN ' num2str(i_i) ')' '''' ',']; 928 | end 929 | for i=1:num_VCVS 930 | interm_string=table_heading{1+num_Nodes+num_V+i}; 931 | interm_string=strrep(interm_string,'_','\_'); 932 | legend_current=[legend_current '''' interm_string ' (RUN ' num2str(i_i) ')' '''' ',']; 933 | end 934 | for i=1:num_CCVS 935 | interm_string=table_heading{1+num_Nodes+num_V+num_VCVS+i}; 936 | interm_string=strrep(interm_string,'_','\_'); 937 | legend_current=[legend_current '''' interm_string ' (RUN ' num2str(i_i) ')' '''' ',']; 938 | end 939 | for i=1:num_L 940 | interm_string=table_heading{1+num_Nodes+num_V+num_VCVS+num_CCVS+i}; 941 | interm_string=strrep(interm_string,'_','\_'); 942 | legend_current=[legend_current '''' interm_string ' (RUN ' num2str(i_i) ')' '''' ',']; 943 | end 944 | if(i_i==runs) 945 | legend_current(end)=')'; 946 | eval(legend_current); 947 | xlabel('TIME (s)'); 948 | ylabel('CURRENTS (A)'); 949 | end 950 | end 951 | if(i_i==runs) %If last run 952 | type('MC_values_ode.txt'); %Display the passive element values used at each run (display the contents of MC_values_ode.txt text file) 953 | fclose(G); %Close MC_values_ode.txt text file 954 | figure(1); %Save the graph(s) 955 | savefig('Voltages_graph.fig'); 956 | if((num_V~=0)||(num_VCVS~=0)||(num_CCVS~=0)||(num_L~=0)) 957 | figure(2); 958 | savefig('Currents_graph.fig'); 959 | end 960 | warning(orig_state); %Restore the warning 'MATLAB:xlswrite:AddSheet' to its original state 961 | end 962 | end 963 | end --------------------------------------------------------------------------------