添加了vcr器件,该器件由电阻改造而来,但是没有解决电阻为0的情况(之后的思路:加一个电压源的branch,在该branch上,当电阻为0时,给电导一个比较大的值,然后给其并联一个电压源)

This commit is contained in:
feng-arch 2024-08-18 23:26:08 +08:00
parent bd01f3ffe0
commit 633fd2aa7e
6 changed files with 221 additions and 18 deletions

View File

@ -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);

View File

@ -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 // !

View File

@ -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

View File

@ -7,6 +7,5 @@
int main() int main()
{ {
test_vcr(); test_vcr();
// test_l6b();
return 0; return 0;
} }

View File

@ -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
View 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;
}