添加了vcr器件,该器件由电阻改造而来,但是没有解决电阻为0的情况(之后的思路:加一个电压源的branch,在该branch上,当电阻为0时,给电导一个比较大的值,然后给其并联一个电压源)
This commit is contained in:
parent
bd01f3ffe0
commit
633fd2aa7e
@ -18,6 +18,7 @@ public:
|
|||||||
std::vector<CCVS> ccvs;
|
std::vector<CCVS> ccvs;
|
||||||
std::vector<Diode> diodes;
|
std::vector<Diode> diodes;
|
||||||
std::vector<Mosfet> mosfets;
|
std::vector<Mosfet> mosfets;
|
||||||
|
std::vector<VCR> vcrs;
|
||||||
|
|
||||||
Circuit() = default;
|
Circuit() = default;
|
||||||
|
|
||||||
@ -43,9 +44,9 @@ public:
|
|||||||
currentSources.emplace_back(node1, node2, current);
|
currentSources.emplace_back(node1, node2, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addVoltageSource(int node1, int node2, double voltage)
|
void addVoltageSource(int node1, int node2, double voltage, std::string type = "DC")
|
||||||
{
|
{
|
||||||
voltageSources.emplace_back(node1, node2, voltage);
|
voltageSources.emplace_back(node1, node2, voltage, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addVCCS(int outputNodePos, int outputNodeNeg, int controlNodePos, int controlNodeNeg, double gm)
|
void addVCCS(int outputNodePos, int outputNodeNeg, int controlNodePos, int controlNodeNeg, double gm)
|
||||||
@ -53,6 +54,11 @@ public:
|
|||||||
vccs.emplace_back(controlNodePos, controlNodeNeg, outputNodePos, outputNodeNeg, gm);
|
vccs.emplace_back(controlNodePos, controlNodeNeg, outputNodePos, outputNodeNeg, gm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addVCR(int outputNodePos, int outputNodeNeg, int controlNodePos, int controlNodeNeg, double gain,std::string type)
|
||||||
|
{
|
||||||
|
vcrs.emplace_back(controlNodePos, controlNodeNeg, outputNodePos, outputNodeNeg, gain,type);
|
||||||
|
}
|
||||||
|
|
||||||
void addVCVS(int outputNodePos, int outputNodeNeg, int controlNodePos, int controlNodeNeg, double gain)
|
void addVCVS(int outputNodePos, int outputNodeNeg, int controlNodePos, int controlNodeNeg, double gain)
|
||||||
{
|
{
|
||||||
vcvs.emplace_back(controlNodePos, controlNodeNeg, outputNodePos, outputNodeNeg, gain);
|
vcvs.emplace_back(controlNodePos, controlNodeNeg, outputNodePos, outputNodeNeg, gain);
|
||||||
|
|||||||
@ -20,7 +20,7 @@ public:
|
|||||||
void add_lc(double dt);
|
void add_lc(double dt);
|
||||||
void load_static_G();
|
void load_static_G();
|
||||||
void load_static_I();
|
void load_static_I();
|
||||||
void updata_I();
|
void updata_I(double time);
|
||||||
void clear_log(std::string filename);
|
void clear_log(std::string filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,6 +29,7 @@ void test_r_v();
|
|||||||
void test_diode();
|
void test_diode();
|
||||||
void test_time();
|
void test_time();
|
||||||
void test_mosfet();
|
void test_mosfet();
|
||||||
void test_vcr();
|
void test_vccs();
|
||||||
void test_l6b();
|
void test_l6b();
|
||||||
|
void test_vcr();
|
||||||
#endif // !
|
#endif // !
|
||||||
@ -1,6 +1,8 @@
|
|||||||
#ifndef DEVICES_HPP
|
#ifndef DEVICES_HPP
|
||||||
#define DEVICES_HPP
|
#define DEVICES_HPP
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
struct Resistor
|
struct Resistor
|
||||||
{
|
{
|
||||||
@ -43,10 +45,12 @@ struct VoltageSource
|
|||||||
int nodeNeg;
|
int nodeNeg;
|
||||||
double voltage;
|
double voltage;
|
||||||
double last_voltage;
|
double last_voltage;
|
||||||
|
std::string votage_cal;
|
||||||
|
|
||||||
VoltageSource(int pos, int neg, double v)
|
VoltageSource(int pos, int neg, double v, std::string votage_cal)
|
||||||
: nodePos(pos), nodeNeg(neg), voltage(v), last_voltage(v) {}
|
: nodePos(pos), nodeNeg(neg), voltage(v), last_voltage(v), votage_cal(votage_cal) {}
|
||||||
};
|
};
|
||||||
|
double get_voltage(VoltageSource voltage, double time);
|
||||||
|
|
||||||
struct VCCS
|
struct VCCS
|
||||||
{
|
{
|
||||||
@ -60,6 +64,20 @@ struct VCCS
|
|||||||
: controlNodePos(cnPos), controlNodeNeg(cnNeg), outputNodePos(onPos), outputNodeNeg(onNeg), transconductance(gm) {}
|
: controlNodePos(cnPos), controlNodeNeg(cnNeg), outputNodePos(onPos), outputNodeNeg(onNeg), transconductance(gm) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VCR
|
||||||
|
{
|
||||||
|
int controlNodePos;
|
||||||
|
int controlNodeNeg;
|
||||||
|
int outputNodePos;
|
||||||
|
int outputNodeNeg;
|
||||||
|
double transresistance;
|
||||||
|
std::string vcr_cal;
|
||||||
|
VCR(int cnPos, int cnNeg, int onPos, int onNeg, double rm, std::string vcr_cal)
|
||||||
|
: controlNodePos(cnPos), controlNodeNeg(cnNeg), outputNodePos(onPos), outputNodeNeg(onNeg), transresistance(rm),vcr_cal(vcr_cal) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
double get_vcr_G(VCR vcr, double U);
|
||||||
|
|
||||||
struct VCVS
|
struct VCVS
|
||||||
{
|
{
|
||||||
int controlNodePos;
|
int controlNodePos;
|
||||||
@ -81,8 +99,8 @@ struct CCCS
|
|||||||
double gain;
|
double gain;
|
||||||
double voltage;
|
double voltage;
|
||||||
|
|
||||||
CCCS(int cnPos, int cnNeg, int onPos, int onNeg, double g,double v)
|
CCCS(int cnPos, int cnNeg, int onPos, int onNeg, double g, double v)
|
||||||
: controlNodePos(cnPos), controlNodeNeg(cnNeg), outputNodePos(onPos), outputNodeNeg(onNeg), gain(g) , voltage(v){}
|
: controlNodePos(cnPos), controlNodeNeg(cnNeg), outputNodePos(onPos), outputNodeNeg(onNeg), gain(g), voltage(v) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CCVS
|
struct CCVS
|
||||||
@ -95,7 +113,7 @@ struct CCVS
|
|||||||
double voltage;
|
double voltage;
|
||||||
|
|
||||||
CCVS(int cnPos, int cnNeg, int onPos, int onNeg, double g, double v)
|
CCVS(int cnPos, int cnNeg, int onPos, int onNeg, double g, double v)
|
||||||
: controlNodePos(cnPos), controlNodeNeg(cnNeg), outputNodePos(onPos), outputNodeNeg(onNeg), gain(g) , voltage(v){}
|
: controlNodePos(cnPos), controlNodeNeg(cnNeg), outputNodePos(onPos), outputNodeNeg(onNeg), gain(g), voltage(v) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Diode
|
struct Diode
|
||||||
|
|||||||
1
main.cpp
1
main.cpp
@ -7,6 +7,5 @@
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test_vcr();
|
test_vcr();
|
||||||
// test_l6b();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -15,6 +15,59 @@ Vector Simulator::dc_solve()
|
|||||||
{
|
{
|
||||||
Matrix G_iter = G; // 复制导纳矩阵
|
Matrix G_iter = G; // 复制导纳矩阵
|
||||||
Vector I_iter = I; // 复制电流矢量
|
Vector I_iter = I; // 复制电流矢量
|
||||||
|
// 处理vcr器件
|
||||||
|
// int vcrI_tempndex = n + circuit.vcvs.size() + circuit.cccs.size() + circuit.ccvs.size() * 2 + circuit.voltageSources.size() + circuit.inductors.size(); // 从电感之后开始
|
||||||
|
for (const auto &vcr : circuit.vcrs)
|
||||||
|
{
|
||||||
|
int cp = vcr.controlNodePos - 1;
|
||||||
|
int cn = vcr.controlNodeNeg - 1;
|
||||||
|
int op = vcr.outputNodePos - 1;
|
||||||
|
int on = vcr.outputNodeNeg - 1;
|
||||||
|
// G=1/kU
|
||||||
|
double U = (cp >= 0 ? V[cp] : 0) - (cn >= 0 ? V[cn] : 0);
|
||||||
|
double G = get_vcr_G(vcr, U);
|
||||||
|
// double out_U = 0;
|
||||||
|
// out_U = (op >= 0 ? V[op] : 0) - (on >= 0 ? V[on] : 0);
|
||||||
|
// if(G==0)
|
||||||
|
// {
|
||||||
|
// out_U = 0;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// out_U = -V[vcrI_tempndex]/G;
|
||||||
|
// }
|
||||||
|
// if (op >= 0 && cp >= 0)
|
||||||
|
// {
|
||||||
|
// G_iter[op][cp] += G;
|
||||||
|
// }
|
||||||
|
// if (op >= 0 && cn >= 0)
|
||||||
|
// {
|
||||||
|
// G_iter[op][cn] -= G;
|
||||||
|
// }
|
||||||
|
// if (on >= 0 && cp >= 0)
|
||||||
|
// {
|
||||||
|
// G_iter[on][cp] -= G;
|
||||||
|
// }
|
||||||
|
// if (on >= 0 && cn >= 0)
|
||||||
|
// {
|
||||||
|
// G_iter[on][cn] += G;
|
||||||
|
// }
|
||||||
|
if(op>=0)
|
||||||
|
{
|
||||||
|
G_iter[op][op] += G;
|
||||||
|
}
|
||||||
|
if(on>=0)
|
||||||
|
{
|
||||||
|
G_iter[on][on] += G;
|
||||||
|
}
|
||||||
|
if(op>0&&on>0)
|
||||||
|
{
|
||||||
|
G_iter[op][on] -= G;
|
||||||
|
G_iter[on][op] -= G;
|
||||||
|
}
|
||||||
|
// I_iter[vcrI_tempndex] = out_U;
|
||||||
|
// vcrI_tempndex++;
|
||||||
|
}
|
||||||
// 处理二极管
|
// 处理二极管
|
||||||
for (const auto &diode : circuit.diodes)
|
for (const auto &diode : circuit.diodes)
|
||||||
{
|
{
|
||||||
@ -188,14 +241,14 @@ void Simulator::load_static_I()
|
|||||||
}
|
}
|
||||||
I = I_temp;
|
I = I_temp;
|
||||||
}
|
}
|
||||||
void Simulator::updata_I()
|
void Simulator::updata_I(double time)
|
||||||
{
|
{
|
||||||
Vector I_temp(n + m); // 电流矢量
|
Vector I_temp(n + m); // 电流矢量
|
||||||
// 添加 DC Voltage Source 的影响
|
// 添加 DC Voltage Source 的影响
|
||||||
int dcI_tempndex = n + circuit.vcvs.size() + circuit.cccs.size() + circuit.ccvs.size() * 2; // 从 CCVS 之后开始
|
int dcI_tempndex = n + circuit.vcvs.size() + circuit.cccs.size() + circuit.ccvs.size() * 2; // 从 CCVS 之后开始
|
||||||
for (auto &dcSource : circuit.voltageSources)
|
for (auto &dcSource : circuit.voltageSources)
|
||||||
{
|
{
|
||||||
double voltage = dcSource.voltage;
|
double voltage = get_voltage(dcSource, time);
|
||||||
if (dcI_tempndex >= 0)
|
if (dcI_tempndex >= 0)
|
||||||
{
|
{
|
||||||
I_temp[dcI_tempndex] += voltage;
|
I_temp[dcI_tempndex] += voltage;
|
||||||
@ -214,6 +267,7 @@ void Simulator::load_static_G()
|
|||||||
m += circuit.ccvs.size() * 2 + circuit.cccs.size();
|
m += circuit.ccvs.size() * 2 + circuit.cccs.size();
|
||||||
m += circuit.voltageSources.size();
|
m += circuit.voltageSources.size();
|
||||||
m += circuit.inductors.size();
|
m += circuit.inductors.size();
|
||||||
|
// m += circuit.vcrs.size();
|
||||||
Matrix G_temp(n + m, n + m); // 导纳矩阵(扩大以包含辅助变量)
|
Matrix G_temp(n + m, n + m); // 导纳矩阵(扩大以包含辅助变量)
|
||||||
// 填充导纳矩阵G_temp和电流矢量I_temp
|
// 填充导纳矩阵G_temp和电流矢量I_temp
|
||||||
for (const auto &resistor : circuit.resistors)
|
for (const auto &resistor : circuit.resistors)
|
||||||
@ -365,6 +419,26 @@ void Simulator::load_static_G()
|
|||||||
}
|
}
|
||||||
dcI_tempndex++;
|
dcI_tempndex++;
|
||||||
}
|
}
|
||||||
|
// 添加VCRS的影响
|
||||||
|
// int vcrI_tempndex = n + circuit.vcvs.size() + circuit.cccs.size() + circuit.ccvs.size() * 2 + circuit.voltageSources.size()+circuit.inductors.size(); // 从 DC Voltage Source 之后开始
|
||||||
|
// for (const auto &vcr : circuit.vcrs)
|
||||||
|
// {
|
||||||
|
// int cp = vcr.controlNodePos - 1;
|
||||||
|
// int cn = vcr.controlNodeNeg - 1;
|
||||||
|
// int op = vcr.outputNodePos - 1;
|
||||||
|
// int on = vcr.outputNodeNeg - 1;
|
||||||
|
// if (on>=0)
|
||||||
|
// {
|
||||||
|
// G_temp[on][vcrI_tempndex] += 1;
|
||||||
|
// G_temp[vcrI_tempndex][on] += 1;
|
||||||
|
// }
|
||||||
|
// if (op>=0)
|
||||||
|
// {
|
||||||
|
// G_temp[op][vcrI_tempndex] -= 1;
|
||||||
|
// G_temp[vcrI_tempndex][op] -= 1;
|
||||||
|
// }
|
||||||
|
// vcrI_tempndex++;
|
||||||
|
// }
|
||||||
G = G_temp;
|
G = G_temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,8 +448,6 @@ Simulator::Simulator(Circuit c)
|
|||||||
circuit = c;
|
circuit = c;
|
||||||
load_static_G();
|
load_static_G();
|
||||||
load_static_I();
|
load_static_I();
|
||||||
G.print();
|
|
||||||
I.print();
|
|
||||||
Vector V(n + m); // 电压矢量
|
Vector V(n + m); // 电压矢量
|
||||||
this->V = V;
|
this->V = V;
|
||||||
}
|
}
|
||||||
@ -434,7 +506,6 @@ int Simulator::time_solve(double dt, double tmax, std::string filename)
|
|||||||
if (time_s - 0.0 < 1e-6)
|
if (time_s - 0.0 < 1e-6)
|
||||||
add_lc(dt);
|
add_lc(dt);
|
||||||
// I.print();
|
// I.print();
|
||||||
updata_I();
|
|
||||||
// I.print();
|
// I.print();
|
||||||
for (int step = 0; step < tmax / dt; ++step)
|
for (int step = 0; step < tmax / dt; ++step)
|
||||||
{
|
{
|
||||||
@ -477,6 +548,33 @@ int Simulator::time_solve(double dt, double tmax, std::string filename)
|
|||||||
{
|
{
|
||||||
Matrix G_iter = G; // 复制导纳矩阵
|
Matrix G_iter = G; // 复制导纳矩阵
|
||||||
Vector I_iter = I; // 复制电流矢量
|
Vector I_iter = I; // 复制电流矢量
|
||||||
|
// 处理vcr器件
|
||||||
|
for (const auto &vcr : circuit.vcrs)
|
||||||
|
{
|
||||||
|
int cp = vcr.controlNodePos - 1;
|
||||||
|
int cn = vcr.controlNodeNeg - 1;
|
||||||
|
int op = vcr.outputNodePos - 1;
|
||||||
|
int on = vcr.outputNodeNeg - 1;
|
||||||
|
// G=1/kU
|
||||||
|
double U = (cp >= 0 ? V[cp] : 0) - (cn >= 0 ? V[cn] : 0);
|
||||||
|
double G = get_vcr_G(vcr, U);
|
||||||
|
if (op >= 0 && cp >= 0)
|
||||||
|
{
|
||||||
|
G_iter[op][cp] += G;
|
||||||
|
}
|
||||||
|
if (op >= 0 && cn >= 0)
|
||||||
|
{
|
||||||
|
G_iter[op][cn] -= G;
|
||||||
|
}
|
||||||
|
if (on >= 0 && cp >= 0)
|
||||||
|
{
|
||||||
|
G_iter[on][cp] -= G;
|
||||||
|
}
|
||||||
|
if (on >= 0 && cn >= 0)
|
||||||
|
{
|
||||||
|
G_iter[on][cn] += G;
|
||||||
|
}
|
||||||
|
}
|
||||||
// 处理二极管
|
// 处理二极管
|
||||||
for (const auto &diode : circuit.diodes)
|
for (const auto &diode : circuit.diodes)
|
||||||
{
|
{
|
||||||
@ -613,6 +711,7 @@ int Simulator::time_solve(double dt, double tmax, std::string filename)
|
|||||||
file << V[i] << " ";
|
file << V[i] << " ";
|
||||||
}
|
}
|
||||||
file << std::endl;
|
file << std::endl;
|
||||||
|
updata_I(time_s);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -713,12 +812,12 @@ void test_mosfet()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_vcr()
|
void test_vccs()
|
||||||
{
|
{
|
||||||
Circuit circuit(3);
|
Circuit circuit(3);
|
||||||
circuit.addVoltageSource(2, 0, 1);
|
circuit.addVoltageSource(2, 0, 1);
|
||||||
circuit.addResistor(1, 0, 1);
|
circuit.addResistor(1, 0, 1);
|
||||||
circuit.addVCCS(2, 1, 1,0, 10);
|
circuit.addVCCS(2, 1, 1, 0, 10);
|
||||||
Simulator simulator(circuit);
|
Simulator simulator(circuit);
|
||||||
Vector v = simulator.dc_solve();
|
Vector v = simulator.dc_solve();
|
||||||
v.print();
|
v.print();
|
||||||
@ -729,10 +828,35 @@ void test_l6b()
|
|||||||
Circuit circuit(3);
|
Circuit circuit(3);
|
||||||
circuit.addResistor(1, 0, 5);
|
circuit.addResistor(1, 0, 5);
|
||||||
circuit.addVCCS(1, 0, 1, 2, 2);
|
circuit.addVCCS(1, 0, 1, 2, 2);
|
||||||
circuit.addResistor(1,2,6);
|
circuit.addResistor(1, 2, 6);
|
||||||
circuit.addResistor(2, 0, 8);
|
circuit.addResistor(2, 0, 8);
|
||||||
circuit.addCurrentSource(0, 2, 10);
|
circuit.addCurrentSource(0, 2, 10);
|
||||||
Simulator simulator(circuit);
|
Simulator simulator(circuit);
|
||||||
Vector v = simulator.dc_solve();
|
Vector v = simulator.dc_solve();
|
||||||
v.print();
|
v.print();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_vcr(double vi)
|
||||||
|
{
|
||||||
|
Circuit circuit(3);
|
||||||
|
circuit.addVoltageSource(1, 0, vi);
|
||||||
|
circuit.addResistor(1, 2, 1000);
|
||||||
|
// circuit.addVCCS(2, 0, 1, 0, 1000, "VCR", "LINEAR");
|
||||||
|
circuit.addVCR(2, 0, 1, 0, 1000, "LINEAR");
|
||||||
|
Simulator simulator(circuit);
|
||||||
|
Vector v = simulator.dc_solve();
|
||||||
|
std::cout << v[2] <<"\t\t"<< v[3] <<"\t\t"<< v[4] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_vcr()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 1500;i++)
|
||||||
|
{
|
||||||
|
test_vcr(i*0.001);
|
||||||
|
}
|
||||||
|
for (int i = 2; i < 150;i++)
|
||||||
|
{
|
||||||
|
test_vcr(i);
|
||||||
|
}
|
||||||
|
// test_vcr(10);
|
||||||
|
}
|
||||||
|
|||||||
55
src/devices.cpp
Normal file
55
src/devices.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include "devices.hpp"
|
||||||
|
|
||||||
|
double get_vcr_G(VCR vcr, double U)
|
||||||
|
{
|
||||||
|
if(vcr.vcr_cal == "CONST")
|
||||||
|
{
|
||||||
|
if(vcr.transresistance == 0)
|
||||||
|
{
|
||||||
|
return 1e20;
|
||||||
|
}
|
||||||
|
return 1/vcr.transresistance;
|
||||||
|
}
|
||||||
|
if(vcr.vcr_cal == "LINEAR")
|
||||||
|
{
|
||||||
|
double R = vcr.transresistance * U;
|
||||||
|
if(R == 0)
|
||||||
|
{
|
||||||
|
return 1e20;
|
||||||
|
}
|
||||||
|
return 1/R;
|
||||||
|
}
|
||||||
|
return 1e20;
|
||||||
|
}
|
||||||
|
|
||||||
|
double get_voltage(VoltageSource voltage, double time)
|
||||||
|
{
|
||||||
|
if (voltage.votage_cal == "CONST")
|
||||||
|
{
|
||||||
|
return voltage.voltage;
|
||||||
|
}
|
||||||
|
if (voltage.votage_cal == "SIN")
|
||||||
|
{
|
||||||
|
return voltage.voltage * sin(2 * M_PI * time);
|
||||||
|
}
|
||||||
|
if (voltage.votage_cal == "PULSE")
|
||||||
|
{
|
||||||
|
if (time < 0)
|
||||||
|
{
|
||||||
|
return voltage.voltage;
|
||||||
|
}
|
||||||
|
if (fmod(time, 1) < 0.5)
|
||||||
|
{
|
||||||
|
return voltage.voltage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -voltage.voltage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (voltage.votage_cal == "DC")
|
||||||
|
{
|
||||||
|
return voltage.voltage * time;
|
||||||
|
}
|
||||||
|
return voltage.voltage;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user