Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Not yet finished] Fix wattmeter probe #946

Open
wants to merge 5 commits into
base: release-0.0.20
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 18 additions & 24 deletions qucs-core/src/components/wprobe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,44 +39,38 @@ wprobe::wprobe () : circuit (4) {
setVoltageSources (1);
}

//NODE 1 --> I+
//NODE 2 --> I-
//NODE 3 --> V+
//NODE 4 --> V-
// voltmeter nodes must be at nodes 1 and 2 as so it's assumed
// in saveNoiseResults() for noise calculations
//NODE 1 --> V+
//NODE 2 --> V-
//NODE 3 --> I+
//NODE 4 --> I-

void wprobe::initDC (void) {
allocMatrixMNA ();
voltageSource (VSRC_1, NODE_1, NODE_2);
voltageSource (VSRC_1, NODE_3, NODE_4);
}

void wprobe::initAC (void) {
initDC ();
}

void wprobe::saveOperatingPoints (void) {
nr_double_t Vr = real (getV (NODE_3) - getV (NODE_4));
nr_double_t Vi = imag (getV (NODE_3) - getV (NODE_4));
nr_double_t Vr = real (getV (NODE_1) - getV (NODE_2));
nr_double_t Vi = imag (getV (NODE_1) - getV (NODE_2));
// operating points as for the vprobe
setOperatingPoint ("Vr", Vr);
setOperatingPoint ("Vi", Vi); //This section works just like a voltmeter
}

//For specific information regarding The Power triangle and Power factor:
//https://en.wikipedia.org/wiki/Power_factor#Definition_and_calculation
setOperatingPoint ("Vi", Vi);

void wprobe::calcOperatingPoints (void) {
//Reading the current and voltage values to calculate power values
nr_double_t VAr = real ((getV (NODE_3) - getV (NODE_4)) * getJ (NODE_1));
nr_double_t VAi = -imag ((getV (NODE_3) - getV (NODE_4)) * getJ (NODE_1));
setOperatingPoint ("VAr", VAr);
setOperatingPoint ("VAi", VAi);

nr_double_t P = VAr;
// read current and voltage values to calculate power values
nr_complex_t Vw = getV (NODE_1) - getV (NODE_2);
nr_complex_t Iw = getJ (VSRC_1);
nr_complex_t Sw = Vw * conj (Iw);
// save P and Q instead of just S since operating points cannot hold complex values
nr_double_t P = real (Sw);
nr_double_t Q = imag (Sw);
setOperatingPoint ("P", P);

nr_double_t Q = VAi;
setOperatingPoint ("Q", Q);
//Power Factor calculation
setOperatingPoint ("PF", P/std::sqrt(P*P+VAi*VAi));
}

void wprobe::initTR (void) {
Expand Down
1 change: 0 additions & 1 deletion qucs-core/src/components/wprobe.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ class wprobe : public qucs::circuit
void initAC (void);
void initTR (void);
void saveOperatingPoints (void);
void calcOperatingPoints (void);
};

#endif /* __WPROBE_H__ */
48 changes: 26 additions & 22 deletions qucs-core/src/nasolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1355,36 +1355,40 @@ void nasolver<nr_type_t>::saveResults (const std::string &volts, const std::stri
circuit * root = subnet->getRoot ();
for (circuit * c = root; c != NULL; c = (circuit *) c->getNext ())
{
// FIXME: operating points are (ab)used in probes to hold probes data
// should be handled differently
// skip if not a probe
if (!c->isProbe ()) continue;
// skip if saving subcircuit components data is not requested
if (!c->getSubcircuit().empty() && !(saveOPs & SAVE_ALL)) continue;
// update probe internal values, if it's not a noise simulation
// values for noise simulation are in acsolver::saveNoiseResults()
if (volts != "vn")
c->saveOperatingPoints ();
std::string n = createOP (c->getName (), volts);
saveVariable (n, nr_complex_t (c->getOperatingPoint ("Vr"),
c->getOperatingPoint ("Vi")), f);

//add watt probe data
c->calcOperatingPoints ();
for (auto ops: c->getOperatingPoints ())
{
//It will only get values if none of the strings are 0
//Once again most of this is adapted from Vprobe and Iprobe
operatingpoint &p = ops.second;
if (strcmp(p.getName(), "Vi") == 0) continue;
if (strcmp(p.getName(), "VAi") == 0) continue;
if (strcmp(p.getName(), "Vr") == 0) continue;
if (strcmp(p.getName(), "VAr") == 0)
{
std::string n = createOP(c->getName(), "S");
saveVariable (n, nr_complex_t (c->getOperatingPoint ("VAr"),
c->getOperatingPoint ("VAi")), f);
continue;
}

std::string n = createOP(c->getName(), p.getName());
saveVariable(n, p.getValue(), f);
}

// add watt probe data
// this is a big hack due to (ab)using the operating points
// for specific information regarding The Power triangle and Power factor:
// https://en.wikipedia.org/wiki/Power_factor#Definition_and_calculation
if (c->hasOperatingPoint("P") && c->hasOperatingPoint("Q")) {
nr_double_t P = c->getOperatingPoint ("P");
nr_double_t Q = c->getOperatingPoint ("Q");
// save complex power
std::string n = createOP(c->getName(), "S");
saveVariable (n, nr_complex_t (P, Q), f);
// save active power
n = createOP(c->getName(), "P");
saveVariable(n, P, f);
// save reactive power
n = createOP(c->getName(), "Q");
saveVariable(n, Q, f);
// save power factor
n = createOP(c->getName(), "PF");
saveVariable(n, P / std::sqrt(P*P + Q*Q), f);
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions qucs/qucs/components/wprobe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,16 @@ wProbe::wProbe()
Lines.append(new Line(-15, 8, -9, 8,QPen(Qt::red,2)));
Lines.append(new Line( 9, 8, 15, 8,QPen(Qt::darkBlue,2)));

//Current Entries
Ports.append(new Port(-30, 0));
Ports.append(new Port( 30, 0));

//Voltage Entries
Lines.append(new Line(-10, 14,-10, 20,QPen(Qt::darkBlue,2)));
Lines.append(new Line( 10, 14, 10, 20,QPen(Qt::darkBlue,2)));
Ports.append(new Port(-10, 20));
Ports.append(new Port( 10, 20));

//Current Entries
Ports.append(new Port(-30, 0));
Ports.append(new Port( 30, 0));

//Letter V
Lines.append(new Line(-3, 7 ,0, 13,QPen(Qt::darkBlue,2)));
Lines.append(new Line( 0, 13, 3, 7,QPen(Qt::darkBlue,2)));
Expand Down