添加了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<Diode> diodes;
|
||||
std::vector<Mosfet> mosfets;
|
||||
std::vector<VCR> vcrs;
|
||||
|
||||
Circuit() = default;
|
||||
|
||||
@ -43,9 +44,9 @@ public:
|
||||
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)
|
||||
@ -53,6 +54,11 @@ public:
|
||||
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)
|
||||
{
|
||||
vcvs.emplace_back(controlNodePos, controlNodeNeg, outputNodePos, outputNodeNeg, gain);
|
||||
|
||||
@ -20,7 +20,7 @@ public:
|
||||
void add_lc(double dt);
|
||||
void load_static_G();
|
||||
void load_static_I();
|
||||
void updata_I();
|
||||
void updata_I(double time);
|
||||
void clear_log(std::string filename);
|
||||
};
|
||||
|
||||
@ -29,6 +29,7 @@ void test_r_v();
|
||||
void test_diode();
|
||||
void test_time();
|
||||
void test_mosfet();
|
||||
void test_vcr();
|
||||
void test_vccs();
|
||||
void test_l6b();
|
||||
void test_vcr();
|
||||
#endif // !
|
||||
@ -1,6 +1,8 @@
|
||||
#ifndef DEVICES_HPP
|
||||
#define DEVICES_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
struct Resistor
|
||||
{
|
||||
@ -43,10 +45,12 @@ struct VoltageSource
|
||||
int nodeNeg;
|
||||
double voltage;
|
||||
double last_voltage;
|
||||
std::string votage_cal;
|
||||
|
||||
VoltageSource(int pos, int neg, double v)
|
||||
: nodePos(pos), nodeNeg(neg), voltage(v), last_voltage(v) {}
|
||||
VoltageSource(int pos, int neg, double v, std::string votage_cal)
|
||||
: nodePos(pos), nodeNeg(neg), voltage(v), last_voltage(v), votage_cal(votage_cal) {}
|
||||
};
|
||||
double get_voltage(VoltageSource voltage, double time);
|
||||
|
||||
struct VCCS
|
||||
{
|
||||
@ -60,6 +64,20 @@ struct VCCS
|
||||
: 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
|
||||
{
|
||||
int controlNodePos;
|
||||
@ -81,8 +99,8 @@ struct CCCS
|
||||
double gain;
|
||||
double voltage;
|
||||
|
||||
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){}
|
||||
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) {}
|
||||
};
|
||||
|
||||
struct CCVS
|
||||
@ -95,7 +113,7 @@ struct CCVS
|
||||
double voltage;
|
||||
|
||||
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
|
||||
|
||||
@ -15,6 +15,59 @@ Vector Simulator::dc_solve()
|
||||
{
|
||||
Matrix G_iter = G; // 复制导纳矩阵
|
||||
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)
|
||||
{
|
||||
@ -188,14 +241,14 @@ void Simulator::load_static_I()
|
||||
}
|
||||
I = I_temp;
|
||||
}
|
||||
void Simulator::updata_I()
|
||||
void Simulator::updata_I(double time)
|
||||
{
|
||||
Vector I_temp(n + m); // 电流矢量
|
||||
// 添加 DC Voltage Source 的影响
|
||||
int dcI_tempndex = n + circuit.vcvs.size() + circuit.cccs.size() + circuit.ccvs.size() * 2; // 从 CCVS 之后开始
|
||||
for (auto &dcSource : circuit.voltageSources)
|
||||
{
|
||||
double voltage = dcSource.voltage;
|
||||
double voltage = get_voltage(dcSource, time);
|
||||
if (dcI_tempndex >= 0)
|
||||
{
|
||||
I_temp[dcI_tempndex] += voltage;
|
||||
@ -214,6 +267,7 @@ void Simulator::load_static_G()
|
||||
m += circuit.ccvs.size() * 2 + circuit.cccs.size();
|
||||
m += circuit.voltageSources.size();
|
||||
m += circuit.inductors.size();
|
||||
// m += circuit.vcrs.size();
|
||||
Matrix G_temp(n + m, n + m); // 导纳矩阵(扩大以包含辅助变量)
|
||||
// 填充导纳矩阵G_temp和电流矢量I_temp
|
||||
for (const auto &resistor : circuit.resistors)
|
||||
@ -365,6 +419,26 @@ void Simulator::load_static_G()
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@ -374,8 +448,6 @@ Simulator::Simulator(Circuit c)
|
||||
circuit = c;
|
||||
load_static_G();
|
||||
load_static_I();
|
||||
G.print();
|
||||
I.print();
|
||||
Vector V(n + m); // 电压矢量
|
||||
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)
|
||||
add_lc(dt);
|
||||
// I.print();
|
||||
updata_I();
|
||||
// I.print();
|
||||
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; // 复制导纳矩阵
|
||||
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)
|
||||
{
|
||||
@ -613,6 +711,7 @@ int Simulator::time_solve(double dt, double tmax, std::string filename)
|
||||
file << V[i] << " ";
|
||||
}
|
||||
file << std::endl;
|
||||
updata_I(time_s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -713,12 +812,12 @@ void test_mosfet()
|
||||
}
|
||||
}
|
||||
|
||||
void test_vcr()
|
||||
void test_vccs()
|
||||
{
|
||||
Circuit circuit(3);
|
||||
circuit.addVoltageSource(2, 0, 1);
|
||||
circuit.addResistor(1, 0, 1);
|
||||
circuit.addVCCS(2, 1, 1,0, 10);
|
||||
circuit.addVCCS(2, 1, 1, 0, 10);
|
||||
Simulator simulator(circuit);
|
||||
Vector v = simulator.dc_solve();
|
||||
v.print();
|
||||
@ -729,10 +828,35 @@ void test_l6b()
|
||||
Circuit circuit(3);
|
||||
circuit.addResistor(1, 0, 5);
|
||||
circuit.addVCCS(1, 0, 1, 2, 2);
|
||||
circuit.addResistor(1,2,6);
|
||||
circuit.addResistor(1, 2, 6);
|
||||
circuit.addResistor(2, 0, 8);
|
||||
circuit.addCurrentSource(0, 2, 10);
|
||||
Simulator simulator(circuit);
|
||||
Vector v = simulator.dc_solve();
|
||||
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