Qucs-S S-parameter Viewer & RF Synthesis Tools
Loading...
Searching...
No Matches
SParameterCalculator.h
Go to the documentation of this file.
1
7
8#ifndef SPARAMETERCALCULATOR_H
9#define SPARAMETERCALCULATOR_H
10
11#include <QFile>
12#include <QList>
13#include <QMap>
14#include <QRegularExpression>
15#include <QString>
16#include <QStringList>
17#include <QTextStream>
18#include <algorithm>
19#include <cmath>
20#include <complex>
21#include <iomanip>
22#include <iostream>
23#include <map>
24#include <sstream>
25#include <stdexcept>
26#include <string>
27#include <vector>
28#include <utility> // std::as_const()
29
30#include "Misc/general.h"
31
32using namespace std;
33using Complex = complex<double>;
34
38 RESISTOR,
39 CAPACITOR,
40 INDUCTOR,
41 VOLTAGE_SOURCE,
42 CURRENT_SOURCE,
43 TRANSMISSION_LINE,
44 OPEN_STUB,
45 SHORT_STUB,
46 COUPLED_LINE,
47 IDEAL_COUPLER,
48 COMPLEX_IMPEDANCE,
49 SPAR_BLOCK,
50 FREQUENCY_DEPENDENT_SPAR_BLOCK,
51 MICROSTRIP_LINE,
52 MICROSTRIP_STEP,
53 MICROSTRIP_OPEN,
54 MICROSTRIP_VIA,
55 MICROSTRIP_COUPLED_LINES
56};
57
63 string name;
64 vector<int> nodes;
65 double frequency;
66 QMap<QString, double> value;
67 QMap<QString, Complex> Zvalue;
68 vector<vector<Complex>> Smatrix;
69 QMap<QString, QList<double>> freqDepData;
72
74 Component_SPAR(ComponentType_SPAR t, const string& n, const vector<int>& nds,
75 const vector<vector<Complex>>& S, int rfPorts,
76 double Z0 = 50.0)
77 : type(t), name(n), nodes(nds), frequency(0.0),
78 Smatrix(S), numRFPorts(rfPorts), referenceImpedance(Z0) {}
79
81 Component_SPAR(ComponentType_SPAR t, const string& n, const vector<int>& nds,
82 QMap<QString, QList<double>> freqData, int rfPorts,
83 double Z0 = 50.0)
84 : type(t), name(n), nodes(nds), frequency(0.0),
85 freqDepData(freqData), numRFPorts(rfPorts), referenceImpedance(Z0) {}
86
88 Component_SPAR(ComponentType_SPAR t, const string& n, const vector<int>& nds,
89 QMap<QString, double> val)
90 : type(t), name(n), nodes(nds), frequency(0.0), value(val) {}
91
93 Component_SPAR(ComponentType_SPAR t, const string& n, const vector<int>& nds,
94 QMap<QString, Complex> zval)
95 : type(t), name(n), nodes(nds), frequency(0.0), Zvalue(zval) {}
96
98 Component_SPAR(ComponentType_SPAR t, const string& n, const vector<int>& nds,
99 const vector<vector<Complex>>& S)
100 : type(t), name(n), nodes(nds), frequency(0.0), Smatrix(S) {}
101
103 Component_SPAR(ComponentType_SPAR t, const string& n, const vector<int>& nds,
104 QMap<QString, QList<double>> freqData)
105 : type(t), name(n), nodes(nds), frequency(0.0), freqDepData(freqData) {}
106};
107
110struct Port {
111 int node;
112 double impedance;
113
117 Port(int n, double z = 50.0) : node(n), impedance(z) {}
118};
119
130private:
131 vector<Component_SPAR> components;
132 vector<Port> ports;
133 int numNodes;
134 double frequency;
135 QString currentNetlist;
136
137 // Matrix operations
138
143 vector<vector<Complex>> createMatrix(int rows, int cols) {
144 return vector<vector<Complex>>(rows, vector<Complex>(cols, Complex(0, 0)));
145 }
146
152 vector<vector<Complex>> invertMatrix(const vector<vector<Complex>>& matrix);
153
158 Complex getImpedance(const Component_SPAR& comp, double freq);
159
162 vector<vector<Complex>> buildAdmittanceMatrix();
163
167 void addCoupledLineToAdmittance(vector<vector<Complex>>& Y,
168 const Component_SPAR& comp);
169
176 vector<vector<Complex>> calculateCoupledLineYMatrix(double Z0e, double Z0o,
177 double length,
178 double freq);
179
183 void addIdealCouplerToAdmittance(vector<vector<Complex>>& Y,
184 const Component_SPAR& comp);
185
191 vector<vector<Complex>>
192 calculateIdealCouplerYMatrix(double k, double phase_deg, double Z0);
193
194
198 void addTransmissionLineToAdmittance(vector<vector<Complex>>& Y,
199 const Component_SPAR& comp);
200
206 vector<vector<Complex>>
207 interpolateFrequencyDependentSMatrix(const Component_SPAR& comp, double freq);
208
215 vector<vector<Complex>> extractSMatrixAtIndex(const Component_SPAR& comp,
216 int freqIndex);
217
223 void addFrequencyDependentSParamBlockToAdmittance(vector<vector<Complex>>& Y,
224 const Component_SPAR& comp);
225
230 vector<vector<Complex>> parseInlineSMatrix(const QString& matrixStr,
231 int numPorts);
232
236 void addOnePortSParamToAdmittance(vector<vector<Complex>>& Y,
237 const Component_SPAR& comp);
238
242 void addTwoPortSParamToAdmittance(vector<vector<Complex>>& Y,
243 const Component_SPAR& comp);
244
251 void addSParameterDevice(const string& name, const vector<int>& nodes,
252 const vector<vector<Complex>>& Smatrix,
253 int numRFPorts, double Z0);
254
256 // Microstrip line analysis methods
257
261 void addMicrostripLineToAdmittance(vector<vector<Complex>>& Y,
262 const Component_SPAR& comp);
263
276 void calcMicrostripPropagation(double W, double h, double er,
277 double t, double tand, double rho,
278 double frequency, double& alpha, double& beta,
279 double& zl, double& ereff);
280
290 void analyseQuasiStatic(double W, double h, double t, double er,
291 const string& Model, double& ZlEff, double& ErEff,
292 double& WEff);
293
304 void analyseDispersion(double W, double h, double er, double ZlEff,
305 double ErEff, double frequency, const string& Model,
306 double& ZlEffFreq, double& ErEffFreq);
307
322 void analyseLoss(double W, double t, double er, double rho, double D,
323 double tand, double ZlEff1, double ZlEff2, double ErEff,
324 double frequency, const string& Model, double& ac,
325 double& ad);
326
327 // Helper functions for microstrip calculations
333 void Hammerstad_ab(double u, double er, double& a, double& b);
334
341 void Hammerstad_er(double u, double er, double a, double b, double& e);
342
346 void Hammerstad_zl(double u, double& zl);
347
354 void Kirschning_er(double u, double fn, double er, double ErEff, double& ErEffFreq);
355
362 void Kirschning_zl(double ErEff, double ErEffFreq, double ZlEff, double& r17, double& ZlEffFreq);
363
365
367 // Microstrip step
371 void addMicrostripStepToAdmittance(vector<vector<Complex>>& Y,
372 const Component_SPAR& comp);
373 void calcMicrostripStepZ(double W1, double W2, double h, double er, double t,
374 double frequency, const string& SModel,
375 const string& DModel, Complex& z11, Complex& z12,
376 Complex& z21, Complex& z22);
378
380 // Microstrip open
384 void addMicrostripOpenToAdmittance(vector<vector<Complex>>& Y,
385 const Component_SPAR& comp);
386
397 Complex calcMicrostripOpenY(double W, double h, double er, double t,
398 double frequency, const string& Model,
399 const string& SModel, const string& DModel);
400
411 double calcMicrostripOpenCend(double W, double h, double er, double t,
412 double frequency, const string& Model,
413 const string& SModel, const string& DModel);
415
421 void addMicrostripViaToAdmittance(vector<vector<Complex>>& Y,
422 const Component_SPAR& comp);
423
431 Complex calcMicrostripViaImpedance(double D, double h, double t, double rho,
432 double frequency);
433
440 double calcMicrostripViaResistance(double D, double h, double t, double rho);
442
448 void addMicrostripCoupledLinesToAdmittance(vector<vector<Complex>>& Y,
449 const Component_SPAR& comp);
450
468 void calcMicrostripCoupledPropagation(double W, double S, double h,
469 double er, double t, double tand,
470 double rho, double frequency,
471 double& alpha_e, double& beta_e,
472 double& zl_e, double& ereff_e,
473 double& alpha_o, double& beta_o,
474 double& zl_o, double& ereff_o);
475
487 void analyseQuasiStaticCoupled(double W, double h, double s, double t,
488 double er, const string& Model, double& Zle,
489 double& Zlo, double& ErEffe, double& ErEffo);
490
507 void analyseDispersionCoupled(double W, double h, double s, double t,
508 double er, double Zle, double Zlo,
509 double ErEffe, double ErEffo, double frequency,
510 const string& DModel, double& ZleFreq,
511 double& ZloFreq, double& ErEffeFreq,
512 double& ErEffoFreq);
513
529 void analyseLossCoupled(double W, double t, double er, double rho,
530 double D, double tand, double ZlEff1, double ZlEff2,
531 double ErEff, double frequency, const string& Model,
532 bool evenMode, double& ac, double& ad);
534
535 // Frequency sweep parameters
536 double f_start = 1e6;
537 double f_stop = 1e9;
538 int n_points = 20;
539
540 // Simulation data
541 std::vector<std::vector<std::vector<Complex>>> sweepResults;
542 QMap<QString, QList<double>> data;
543
548 double parseScaledValue(const QString& input,
549 QString unit_type = QString(""));
550
551public:
553 SParameterCalculator() : numNodes(0), frequency(1e9) {}
554
558 bool setNetlist(const QString &netlist) {
559 currentNetlist = netlist;
560 return parseNetlist();
561 }
562
564 const QString& getNetlist() const { return currentNetlist; }
565
567 void addComponent(ComponentType_SPAR type, const string& name,
568 const vector<int>& nodes, QMap<QString, double> value);
569
571 void addComponent(ComponentType_SPAR type, const string& name,
572 const vector<int>& nodes, QMap<QString, Complex> Zvalue);
573
575 void addComponent(ComponentType_SPAR type, const string& name,
576 const vector<int>& nodes,
577 QMap<QString, QList<double>> freqDepData);
578
582 void addPort(int node, double impedance = 50.0);
583
586 vector<vector<Complex>> calculateSParameters();
587
588 // SPAR Block component
590 vector<vector<Complex>> convertS2Y(const vector<vector<Complex>>& S,
591 double Z0);
592
594 void addSParamBlockToAdmittance(vector<vector<Complex>>& Y,
595 const Component_SPAR& comp);
596
598
599 void addSParameterBlock(const string& name, const vector<int>& nodes,
600 const vector<vector<Complex>>& Smatrix);
601
603 void printSParameters(const vector<vector<Complex>>& S);
604
606 void exportTouchstone(const QString& filename,
607 const vector<vector<Complex>>& S);
608
610 void clear(){
611 components.clear();
612 ports.clear();
613 numNodes = 0;
614 }
615
616 // Getter methods
618 int getNumNodes() const { return numNodes; }
619
621 size_t getNumComponents() const { return components.size(); }
622
624 size_t getNumPorts() const { return ports.size(); }
625
627 double getFrequency() const { return frequency; }
628
630 QMap<QString, QList<double>> getData() { return data; }
631
632 // Setter methods
634 void setFrequency(double freq) { frequency = freq; }
635
637 void setFrequencySweep(double start, double stop, int points);
638
641
643 void printSParameterSweep() const;
644
646 void exportSweepTouchstone(const QString& filename) const;
647
648private:
652 bool parseNetlist();
653};
654
655#endif // SPARAMETERCALCULATOR_H
ComponentType_SPAR
Circuit component types supported in S-parameter analysis.
Definition SParameterCalculator.h:37
Calculates S-parameters using nodal analysis.
Definition SParameterCalculator.h:129
vector< vector< Complex > > calculateSParameters()
Calculates S-parameters at current frequency.
Definition SParameterCalculator.cpp:177
void exportSweepTouchstone(const QString &filename) const
Exports frequency sweep to Touchstone file.
Definition output.cpp:44
void addComponent(ComponentType_SPAR type, const string &name, const vector< int > &nodes, QMap< QString, double > value)
Adds lumped component with real-valued parameters.
Definition SParameterCalculator.cpp:159
void printSParameterSweep() const
Prints all S-parameters from stored sweep.
Definition output.cpp:102
void addPort(int node, double impedance=50.0)
Adds port to circuit.
Definition SParameterCalculator.cpp:173
void exportTouchstone(const QString &filename, const vector< vector< Complex > > &S)
Exports S-parameters to Touchstone file format.
Definition output.cpp:11
void printSParameters(const vector< vector< Complex > > &S)
Prints S-parameters in readable format to console.
Definition output.cpp:84
vector< vector< Complex > > convertS2Y(const vector< vector< Complex > > &S, double Z0)
Converts S-parameters to Y-parameters.
Definition SP_Component.cpp:12
size_t getNumComponents() const
Returns number of components in circuit.
Definition SParameterCalculator.h:621
QMap< QString, QList< double > > getData()
Returns formatted sweep data.
Definition SParameterCalculator.h:630
void addSParameterBlock(const string &name, const vector< int > &nodes, const vector< vector< Complex > > &Smatrix)
Adds S-parameter block component.
Definition SP_Component.cpp:215
SParameterCalculator()
Constructor.
Definition SParameterCalculator.h:553
void setFrequencySweep(double start, double stop, int points)
Configures frequency sweep parameters.
Definition SParameterCalculator.cpp:250
bool setNetlist(const QString &netlist)
Sets netlist and parses components.
Definition SParameterCalculator.h:558
const QString & getNetlist() const
Returns current netlist string.
Definition SParameterCalculator.h:564
size_t getNumPorts() const
Returns number of ports defined.
Definition SParameterCalculator.h:624
void calculateSParameterSweep()
Performs S-parameter calculation over frequency sweep.
Definition SParameterCalculator.cpp:257
void addSParamBlockToAdmittance(vector< vector< Complex > > &Y, const Component_SPAR &comp)
Adds S-parameter block to admittance matrix.
Definition SP_Component.cpp:45
double getFrequency() const
Returns current analysis frequency.
Definition SParameterCalculator.h:627
void setFrequency(double freq)
Sets current analysis frequency.
Definition SParameterCalculator.h:634
int getNumNodes() const
Returns total number of circuit nodes.
Definition SParameterCalculator.h:618
void clear()
Clears all components and ports.
Definition SParameterCalculator.h:610
Utility functions needed across the whole project.
Circuit component structure.
Definition SParameterCalculator.h:61
Component_SPAR(ComponentType_SPAR t, const string &n, const vector< int > &nds, QMap< QString, QList< double > > freqData)
Constructor for frequency-dependent impedance.
Definition SParameterCalculator.h:103
Component_SPAR(ComponentType_SPAR t, const string &n, const vector< int > &nds, const vector< vector< Complex > > &S, int rfPorts, double Z0=50.0)
Constructor for S-parameter network block with matrix.
Definition SParameterCalculator.h:74
int numRFPorts
Number of RF ports for network blocks.
Definition SParameterCalculator.h:70
QMap< QString, QList< double > > freqDepData
Frequency-dependent data tables.
Definition SParameterCalculator.h:69
Component_SPAR(ComponentType_SPAR t, const string &n, const vector< int > &nds, QMap< QString, double > val)
Constructor for lumped components with real parameters.
Definition SParameterCalculator.h:88
QMap< QString, Complex > Zvalue
Complex impedance values.
Definition SParameterCalculator.h:67
string name
Component name/label.
Definition SParameterCalculator.h:63
Component_SPAR(ComponentType_SPAR t, const string &n, const vector< int > &nds, QMap< QString, QList< double > > freqData, int rfPorts, double Z0=50.0)
Constructor for frequency-dependent S-parameter block.
Definition SParameterCalculator.h:81
double frequency
Operating frequency for frequency-dependent components.
Definition SParameterCalculator.h:65
ComponentType_SPAR type
Component type identifier.
Definition SParameterCalculator.h:62
double referenceImpedance
Reference impedance (typically 50Ω)
Definition SParameterCalculator.h:71
vector< vector< Complex > > Smatrix
S-parameter matrix for network blocks.
Definition SParameterCalculator.h:68
Component_SPAR(ComponentType_SPAR t, const string &n, const vector< int > &nds, QMap< QString, Complex > zval)
Constructor for complex impedance components.
Definition SParameterCalculator.h:93
Component_SPAR(ComponentType_SPAR t, const string &n, const vector< int > &nds, const vector< vector< Complex > > &S)
Constructor for S-parameter device without port count.
Definition SParameterCalculator.h:98
vector< int > nodes
Node connectivity list.
Definition SParameterCalculator.h:64
QMap< QString, double > value
Real-valued parameters (R, L, C, etc.)
Definition SParameterCalculator.h:66
Network port definition with node and impedance.
Definition SParameterCalculator.h:110
double impedance
Port characteristic impedance (typically 50Ω)
Definition SParameterCalculator.h:112
int node
Node number where port is connected.
Definition SParameterCalculator.h:111
Port(int n, double z=50.0)
Constructor with default 50Ω impedance.
Definition SParameterCalculator.h:117