├── Solver.PNG ├── Executable File └── input.txt ├── Src ├── Circuits │ ├── input.txt │ ├── Component.h │ ├── Circuits.vcxproj.filters │ ├── Circuits.vcxproj │ └── Solver.cpp ├── Circuits.sdf ├── Circuits.v11.suo ├── .vs │ └── Circuits │ │ └── v14 │ │ └── .suo └── Circuits.sln ├── Project Description.pdf ├── .gitignore ├── README.md └── LICENSE /Solver.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdallahHemdan/Circuits-Solver/HEAD/Solver.PNG -------------------------------------------------------------------------------- /Executable File/input.txt: -------------------------------------------------------------------------------- 1 | 50 2 | Vs 0 1 10 30 3 | L1 1 2 0.001 4 | C1 2 3 0.0001 5 | R1 3 0 10 -------------------------------------------------------------------------------- /Src/Circuits/input.txt: -------------------------------------------------------------------------------- 1 | 50 2 | Vs 0 1 10 30 3 | L1 1 2 0.001 4 | C1 2 3 0.0001 5 | R1 3 0 10 -------------------------------------------------------------------------------- /Src/Circuits.sdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdallahHemdan/Circuits-Solver/HEAD/Src/Circuits.sdf -------------------------------------------------------------------------------- /Src/Circuits.v11.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdallahHemdan/Circuits-Solver/HEAD/Src/Circuits.v11.suo -------------------------------------------------------------------------------- /Project Description.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdallahHemdan/Circuits-Solver/HEAD/Project Description.pdf -------------------------------------------------------------------------------- /Src/.vs/Circuits/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbdallahHemdan/Circuits-Solver/HEAD/Src/.vs/Circuits/v14/.suo -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /Src/Circuits/Component.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace Eigen; 10 | using namespace std; 11 | 12 | // Component Elements 13 | struct Component 14 | { 15 | string name; 16 | complex voltage; 17 | complex current; 18 | complex Z; 19 | complex Y; 20 | int node1, node2, VS_num; 21 | double factor; 22 | }; 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 🔌Circuits Solver 2 | 3 | Circuits Solver ia a simple tool to simulate and solve AC circuits. 4 | 5 | ## 🎯The project objective 6 | 7 | The mission is to develop a CAD (Computer Aided Design) tool 8 | to simulate simple AC circuits that contains : 9 | 10 |
    11 |
  1. independent voltage sources
  2. 12 |
  3. independent current sources
  4. 13 |
  5. dependent voltage source
  6. 14 |
  7. dependent current source
  8. 15 |
  9. resistors
  10. 16 |
  11. capacitors
  12. 17 |
  13. inductors
  14. 18 |
19 | 20 |

21 | 22 |

23 | -------------------------------------------------------------------------------- /Src/Circuits.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Circuits", "Circuits\Circuits.vcxproj", "{3420B93C-2197-4CF5-895D-B9B0245484B8}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {3420B93C-2197-4CF5-895D-B9B0245484B8}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {3420B93C-2197-4CF5-895D-B9B0245484B8}.Debug|Win32.Build.0 = Debug|Win32 14 | {3420B93C-2197-4CF5-895D-B9B0245484B8}.Release|Win32.ActiveCfg = Release|Win32 15 | {3420B93C-2197-4CF5-895D-B9B0245484B8}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Abdallah Hemdan 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 | -------------------------------------------------------------------------------- /Src/Circuits/Circuits.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Source Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /Src/Circuits/Circuits.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {3420B93C-2197-4CF5-895D-B9B0245484B8} 15 | Circuits 16 | 17 | 18 | 19 | Application 20 | true 21 | v110 22 | MultiByte 23 | 24 | 25 | Application 26 | false 27 | v110 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Level3 45 | Disabled 46 | C:\Users\hp\Desktop\Eigen 47 | 48 | 49 | true 50 | 51 | 52 | 53 | 54 | Level3 55 | MaxSpeed 56 | true 57 | true 58 | 59 | 60 | true 61 | true 62 | true 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Src/Circuits/Solver.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "Component.h" 8 | 9 | using namespace Eigen; 10 | using namespace std; 11 | 12 | 13 | const double PI = 3.141592; 14 | double w; 15 | int VS_num = 0, CS_num = 0, R_num = 0, L_num = 0, C_num = 0, nodes_num = 0; 16 | ifstream input; 17 | ofstream output; 18 | vector components; 19 | 20 | 21 | // Read The input from external file 22 | bool read() 23 | { 24 | string s; 25 | cout << "Enter INPUT file name: "; 26 | cin >> s; 27 | input.open(s + ".txt"); 28 | if (input.is_open()) 29 | { 30 | input >> s; 31 | w = stoi(s); 32 | 33 | while (!input.eof()) 34 | { 35 | input >> s; 36 | if (s == "Vs") 37 | { 38 | string n1, n2, mag, phase; 39 | Component VScource; 40 | VScource.name = s; 41 | input >> n1 >> n2 >> mag >> phase; 42 | 43 | VScource.node1 = stoi(n1); 44 | VScource.node2 = stoi(n2); 45 | 46 | double magn = stod(mag); 47 | double ph = stod(phase); 48 | 49 | VScource.voltage = complex(magn * cos(ph * PI / 180), 50 | magn * sin(ph * PI / 180)); 51 | 52 | components.push_back(VScource); 53 | VS_num++; 54 | } 55 | else if (s == "Cs") 56 | { 57 | string n1, n2, mag, phase; 58 | Component SScource; 59 | SScource.name = s; 60 | 61 | input >> n1 >> n2 >> mag >> phase; 62 | 63 | SScource.node1 = stoi(n1); 64 | SScource.node2 = stoi(n2); 65 | 66 | double magn = stod(mag); 67 | double ph = stod(phase); 68 | 69 | SScource.current = complex(magn * cos(ph * PI / 180), 70 | magn * sin(ph * PI / 180)); 71 | components.push_back(SScource); 72 | 73 | CS_num++; 74 | } 75 | 76 | else if (s[0] == 'R') 77 | { 78 | string n1, n2, mag; 79 | Component R; 80 | R.name = s; 81 | input >> n1 >> n2 >> mag; 82 | R.node1 = stoi(n1); 83 | R.node2 = stoi(n2); 84 | 85 | float magn = stof(mag); 86 | R.Z = complex(magn, 0); 87 | 88 | R.Y = pow(R.Z, -1); 89 | R.factor = 0; 90 | components.push_back(R); 91 | R_num++; 92 | } 93 | else if (s[0] == 'C') 94 | { 95 | string n1, n2, factor; 96 | Component C; 97 | C.name = s; 98 | 99 | input >> n1 >> n2 >> factor; 100 | 101 | C.node1 = stoi(n1); 102 | C.node2 = stoi(n2); 103 | double magn = stod(factor); 104 | 105 | C.Z = complex(0, -1 / (w * magn)); 106 | C.Y = pow(C.Z, -1); 107 | 108 | C.factor = magn; 109 | components.push_back(C); 110 | C_num++; 111 | } 112 | else if (s[0] == 'L') 113 | { 114 | string n1, n2, factor; 115 | Component L; 116 | L.name = s; 117 | 118 | input >> n1 >> n2 >> factor; 119 | 120 | L.node1 = stoi(n1); 121 | L.node2 = stoi(n2); 122 | 123 | double magn = stod(factor); 124 | 125 | L.Z = complex(0, w * magn); 126 | L.Y = pow(L.Z, -1); //(0, -1/(w*magn)); 127 | L.factor = magn; 128 | 129 | components.push_back(L); 130 | L_num++; 131 | } 132 | } 133 | } 134 | else 135 | { 136 | cout << "Wrong name, Enter a valid name\n"; 137 | return false; 138 | } 139 | return true; 140 | } 141 | 142 | int main() 143 | { 144 | if (read()) 145 | ; 146 | else 147 | { 148 | while (true) 149 | { 150 | cout << "Please Enter a valid name\n"; 151 | if (read()) 152 | break; 153 | } 154 | } 155 | 156 | for (int i = 0; i < components.size(); ++i) 157 | { 158 | if (components[i].node1 > nodes_num) 159 | nodes_num = components[i].node1; 160 | if (components[i].node2 > nodes_num) 161 | nodes_num = components[i].node2; 162 | } 163 | 164 | int Eqs = nodes_num; 165 | for (int i = 0; i < components.size(); ++i) 166 | { 167 | if (components[i].name == "Vs") 168 | { 169 | Eqs++; 170 | components[i].VS_num = Eqs; 171 | } 172 | } 173 | 174 | Eigen::MatrixXcd Ys(Eqs, Eqs); 175 | Eigen::MatrixXcd VS(Eqs, 1); 176 | Eigen::MatrixXcd IS(Eqs, 1); 177 | 178 | for (int i = 0; i < Eqs; ++i) 179 | for (int j = 0; j < Eqs; ++j) 180 | Ys(i, j).imag(0), Ys(i, j).real(0); 181 | 182 | for (int i = 0; i < Eqs; ++i) 183 | { 184 | VS(i, 0).imag(0); 185 | VS(i, 0).real(0); 186 | 187 | IS(i, 0).imag(0); 188 | IS(i, 0).real(0); 189 | } 190 | 191 | vector > Vnodes(nodes_num); 192 | for (int i = 0; i < components.size(); ++i) 193 | { 194 | // first of all, if we have a voltage source 195 | if (components[i].node1 == 0 && components[i].name == "Vs") 196 | { 197 | // Vnodes[components[i].node2] = components[i].voltage; 198 | Ys(components[i].node2 - 1, components[i].VS_num - 1) += complex(-1, 0); 199 | Ys(components[i].VS_num - 1, components[i].node2 - 1) += complex(-1, 0); 200 | VS(components[i].VS_num - 1, 0) += components[i].voltage; 201 | } 202 | else if (components[i].node2 == 0 && components[i].name == "Vs") 203 | { 204 | Ys(components[i].node1 - 1, components[i].VS_num - 1) += complex(1, 0); 205 | Ys(components[i].VS_num - 1, components[i].node1 - 1) += complex(1, 0); 206 | VS(components[i].VS_num - 1, 0) += components[i].voltage; 207 | } 208 | else if (components[i].node1 != 0 && components[i].node2 != 0 209 | && components[i].name == "Vs") // same as previus but we have two additional equations 210 | { 211 | Ys(components[i].node1 - 1, components[i].VS_num - 1) += complex(1, 0); 212 | Ys(components[i].node2 - 1, components[i].VS_num - 1) += complex(-1, 0); 213 | Ys(components[i].VS_num - 1, components[i].node1 - 1) += complex(1, 0); 214 | Ys(components[i].VS_num - 1, components[i].node2 - 1) += complex(-1, 0); 215 | VS(components[i].VS_num - 1, 0) += components[i].voltage; 216 | } 217 | 218 | // If we have current sources 219 | else if (components[i].name == "Cs" && components[i].node1 == 0) 220 | { 221 | VS(components[i].node2 - 1, 0) -= components[i].current; 222 | } 223 | else if (components[i].name == "Cs" && components[i].node2 == 0) 224 | { 225 | VS(components[i].node1 - 1, 0) += components[i].current; 226 | } 227 | else if (components[i].name == "Cs" && components[i].node1 != 0 && components[i].node2 != 0) 228 | { 229 | VS(components[i].node2 - 1, 0) -= components[i].current; 230 | VS(components[i].node1 - 1, 0) += components[i].current; 231 | } 232 | 233 | // Now if we have passive components 234 | else if (components[i].name[0] == 'R' || components[i].name[0] == 'C' 235 | || components[i].name[0] == 'L') 236 | { 237 | if (components[i].node1 == 0) 238 | { 239 | Ys(components[i].node2 - 1, components[i].node2 - 1) += components[i].Y; 240 | } 241 | else if (components[i].node2 == 0) 242 | { 243 | Ys(components[i].node1 - 1, components[i].node1 - 1) += components[i].Y; 244 | } 245 | else if (components[i].node1 != 0 && components[i].node2 != 0) 246 | { 247 | Ys(components[i].node1 - 1, components[i].node1 - 1) += components[i].Y; 248 | Ys(components[i].node2 - 1, components[i].node1 - 1) -= components[i].Y; 249 | Ys(components[i].node2 - 1, components[i].node2 - 1) += components[i].Y; 250 | Ys(components[i].node1 - 1, components[i].node2 - 1) += components[i].Y; 251 | } 252 | } 253 | } 254 | 255 | IS += Ys.jacobiSvd(ComputeThinU | ComputeThinV).solve(VS); 256 | cout << "\n"; 257 | 258 | cout << Ys << "\n\n\n"; 259 | cout << VS << "\n\n\n"; 260 | cout << IS; 261 | cout << "\n"; 262 | 263 | 264 | for (int i = 0; i < Eqs; i++) 265 | { 266 | 267 | IS(i, 0).real(int(IS(i, 0).real() * 1000) / 1000.0); 268 | IS(i, 0).imag(int(IS(i, 0).imag() * 1000) / 1000.0); 269 | } 270 | int i = 0; 271 | for (; i < nodes_num; i++) 272 | { 273 | cout << "V(" << i + 1 << ")" 274 | << " " << abs(IS(i, 0)) << " " << (arg(IS(i, 0)) * (180 / 3.141592654)); 275 | cout << endl; 276 | } 277 | for (int j = 0; j < nodes_num; j++) 278 | { 279 | if (components[j].name == "Vs") 280 | { 281 | cout << "I(" << components[j].node1 << " " << components[j].node2 << ")" 282 | << " " << abs(IS(i, 0)) << " " << (arg(IS(i, 0)) * (180 / 3.141592654)); 283 | i++; 284 | cout << endl; 285 | } 286 | if (components[j].name == "Is") 287 | { 288 | cout << "I(" << components[j].node2 << " " << components[j].node1 << ")" 289 | << " " << abs(components[j].current) << " " 290 | << (arg(components[j].current) * (180 / 3.141592654)); 291 | cout << endl; 292 | } 293 | if (components[j].name[0] == 'R' || components[j].name[0] == 'L' 294 | || components[j].name[0] == 'C') 295 | { 296 | if (components[j].node1 != 0 && components[j].node1 != 0) 297 | { 298 | complex I 299 | = ((IS(components[j].node1 - 1, 0) - IS(components[j].node2 - 1, 0)) 300 | / components[j].Z); 301 | cout << "I(" << components[j].node1 << " " << components[j].node2 << ")" 302 | << " " << abs(I) << " " << (arg(I) * (180 / 3.141592654)); 303 | cout << endl; 304 | } 305 | else 306 | { 307 | if (components[j].node1 == 0) 308 | { 309 | complex I = ((complex(0, 0) - IS(components[j].node2 - 1, 0)) 310 | / components[j].Z); 311 | cout << "I(" << components[j].node1 << " " << components[j].node2 << ")" 312 | << " " << abs(I) << " " << (arg(I) * (180 / 3.141592654)); 313 | cout << endl; 314 | } 315 | else if (components[j].node2 == 0) 316 | { 317 | complex I = ((IS(components[j].node1 - 1, 0)) / components[j].Z); 318 | cout << "I(" << components[j].node1 << " " << components[j].node2 << ")" 319 | << " " << abs(I) << " " << (arg(I) * (180 / 3.141592654)); 320 | cout << endl; 321 | } 322 | } 323 | } 324 | } 325 | system("PAUSE"); 326 | return 0; 327 | } --------------------------------------------------------------------------------