Skip to content
5 changes: 4 additions & 1 deletion src/processors/CircuitSimulatorInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,8 +484,11 @@
else if (programName == CircuitSimulatorExporterModels::LTSPICE) {
return std::make_shared<CircuitSimulatorExporterLtspiceModel>();
}
else if (programName == CircuitSimulatorExporterModels::PLECS) {
return std::make_shared<CircuitSimulatorExporterPlecsModel>();
}
else
throw ModelNotAvailableException("Unknown Circuit Simulator program, available options are: {SIMBA, NGSPICE, LTSPICE}");
throw ModelNotAvailableException("Unknown Circuit Simulator program, available options are: {SIMBA, NGSPICE, LTSPICE, PLECS}");
}

std::string CircuitSimulatorExporter::export_magnetic_as_subcircuit(Magnetic magnetic, double frequency, double temperature, std::optional<std::string> outputFilename, std::optional<std::string> filePathOrFile, CircuitSimulatorExporterCurveFittingModes mode) {
Expand Down Expand Up @@ -995,45 +998,45 @@
coordinates[1] += numberCoreLadderPairElements * 6 - 5;

windingJson = create_winding(winding.get_number_turns(), coordinates, 0, winding.get_name());
// {
// std::vector<int> connectorTopCoordinates = {coordinates[0], coordinates[1] + 1};
// std::vector<int> connectorBottomCoordinates = {coordinates[0] - 6, coordinates[1] + 1};

Check warning on line 1003 in src/processors/CircuitSimulatorInterface.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the commented out code.

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9KqgsCLsiQJ0fnWd&open=AZ1H9KqgsCLsiQJ0fnWd&pullRequest=57

// auto connectorJson = create_connector(connectorBottomCoordinates, connectorTopCoordinates, "Top connector core losses");
// device["SubcircuitDefinition"]["Connectors"].push_back(connectorJson);
// }
// {
// std::vector<int> connectorTopCoordinates = {coordinates[0], coordinates[1] + 5};
// std::vector<int> connectorBottomCoordinates = {coordinates[0] - 12, coordinates[1] + 1};

Check warning on line 1010 in src/processors/CircuitSimulatorInterface.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the commented out code.

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9KqgsCLsiQJ0fnWe&open=AZ1H9KqgsCLsiQJ0fnWe&pullRequest=57

// auto connectorJson = create_connector(connectorTopCoordinates, connectorBottomCoordinates, "Bottom connector core losses");
// device["SubcircuitDefinition"]["Connectors"].push_back(connectorJson);
// }
{
std::vector<int> connectorTopCoordinates = {windingCoordinates[0] + 2, windingCoordinates[1]};
// std::vector<int> connectorBottomCoordinates = {coordinates[0] + 2, coordinates[1] + 1};

Check warning on line 1017 in src/processors/CircuitSimulatorInterface.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the commented out code.

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9KqgsCLsiQJ0fnWg&open=AZ1H9KqgsCLsiQJ0fnWg&pullRequest=57
std::vector<int> connectorBottomCoordinates = {coordinates[0] + 2, coordinates[1] + 5};

auto connectorJson = create_connector(connectorTopCoordinates, connectorBottomCoordinates, "Central column connector to core losses");
device["SubcircuitDefinition"]["Connectors"].push_back(connectorJson);
}

// coordinates[0] -= 6;
// auto aux = create_ladder(coreResistanceCoefficients, coordinates, winding.get_name());
// if (coreResistanceCoefficients.size() > 0) {
// coordinates[0] -= 6;
// }
// ladderJsons = aux.first;
// ladderConnectorsJsons = aux.second;

Check warning on line 1030 in src/processors/CircuitSimulatorInterface.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the commented out code.

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9KqgsCLsiQJ0fnWh&open=AZ1H9KqgsCLsiQJ0fnWh&pullRequest=57

// device["SubcircuitDefinition"]["Devices"].push_back(windingJson);

// for (auto ladderJson : ladderJsons) {
// device["SubcircuitDefinition"]["Devices"].push_back(ladderJson);
// }
// for (auto ladderConnectorsJson : ladderConnectorsJsons) {
// device["SubcircuitDefinition"]["Connectors"].push_back(ladderConnectorsJson);
// }

Check warning on line 1039 in src/processors/CircuitSimulatorInterface.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the commented out code.

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9KqgsCLsiQJ0fnWi&open=AZ1H9KqgsCLsiQJ0fnWi&pullRequest=57
}

for (auto deviceJson : device["SubcircuitDefinition"]["Devices"]) {
Expand Down Expand Up @@ -2469,7 +2472,7 @@
c.px=px; c.py=py; c.angle=angle;
cmps += nl5_cmp_to_xml(c);
};
auto add_K = [&](const std::string& name, int Lid1, int Lid2, double k, int px, int py) {

Check warning on line 2475 in src/processors/CircuitSimulatorInterface.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this const reference to "std::string" by a "std::string_view".

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9KqgsCLsiQJ0fnWW&open=AZ1H9KqgsCLsiQJ0fnWW&pullRequest=57
Nl5Cmp c; c.type="K_K"; c.id=nextId++; c.name=name;
c.node0=Lid1; c.node1=Lid2; // NL5 uses node0/node1 as inductor IDs for K
c.valParam="k"; c.valStr=to_string(k,8);
Expand Down Expand Up @@ -2499,7 +2502,7 @@

// Add port wire labels (external terminals)
cmps += nl5_wire_to_xml(nextId++, node_Pplus, node_Pplus, 0, base_y, -20, base_y, "P"+ws+"+");
cmps += nl5_wire_to_xml(nextId++, node_Pminus, node_Pminus, 160, base_y+40, 180, base_y+40, "P"+ws+"-");

Check warning on line 2505 in src/processors/CircuitSimulatorInterface.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract the assignment from this expression.

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9KqgsCLsiQJ0fnWX&open=AZ1H9KqgsCLsiQJ0fnWX&pullRequest=57

// 1. Rdc
add_R("Rdc"+ws, node_Pplus, node_after_rdc, Rdc, 20, base_y);
Expand Down Expand Up @@ -2560,7 +2563,7 @@
int node_stage = 900 + static_cast<int>(k);
add_R("Rcore"+std::to_string(k), node_core_p, node_stage,
net.stages[k].R * net.opts.coef, 100, static_cast<int>(numWindings)*80 + static_cast<int>(k)*16);
add_C("Ccore"+std::to_string(k), node_stage, node_core_n,

Check warning on line 2566 in src/processors/CircuitSimulatorInterface.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use std::format instead of concatenating pieces manually.

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9KqgsCLsiQJ0fnWZ&open=AZ1H9KqgsCLsiQJ0fnWZ&pullRequest=57
net.stages[k].C / net.opts.coef, 104, static_cast<int>(numWindings)*80 + static_cast<int>(k)*16 + 20, 90);
}
if (net.Cinf > 0.0)
Expand All @@ -2572,9 +2575,9 @@
int node_prev = node_core_p;
for (size_t k = 0; k < coreStages; ++k) {
int node_stage = 900 + static_cast<int>(k);
add_R("Rcore"+std::to_string(k), node_prev, node_stage,

Check warning on line 2578 in src/processors/CircuitSimulatorInterface.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use std::format instead of concatenating pieces manually.

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9KqgsCLsiQJ0fnWa&open=AZ1H9KqgsCLsiQJ0fnWa&pullRequest=57
coreCoeffs[2*k], 100, static_cast<int>(numWindings)*80 + static_cast<int>(k)*16);
add_C("Ccore"+std::to_string(k), node_stage, node_core_n,

Check warning on line 2580 in src/processors/CircuitSimulatorInterface.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use std::format instead of concatenating pieces manually.

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9KqgsCLsiQJ0fnWb&open=AZ1H9KqgsCLsiQJ0fnWb&pullRequest=57
coreCoeffs[2*k+1], 104, static_cast<int>(numWindings)*80 + static_cast<int>(k)*16 + 20, 90);
node_prev = node_stage;
}
Expand All @@ -2589,7 +2592,7 @@
double Lmag_val = magnetizingInductance;
if (leakage >= Lmag_val) leakage = Lmag_val * 0.1;
double k_coupling = std::sqrt((Lmag_val - leakage) / Lmag_val);
add_K("K"+std::to_string(i+1)+std::to_string(j+1),

Check warning on line 2595 in src/processors/CircuitSimulatorInterface.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use std::format instead of concatenating pieces manually.

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9KqgsCLsiQJ0fnWc&open=AZ1H9KqgsCLsiQJ0fnWc&pullRequest=57
lmag_ids[i], lmag_ids[j], k_coupling,
140, static_cast<int>(i+j)*20);
}
Expand Down
34 changes: 33 additions & 1 deletion src/processors/CircuitSimulatorInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,8 @@
SIMBA,
NGSPICE,
LTSPICE,
NL5
NL5,
PLECS
};

void from_json(const json & j, CircuitSimulatorExporterModels & x);
Expand All @@ -419,6 +420,7 @@
else if (j == "NgSpice") x = CircuitSimulatorExporterModels::NGSPICE;
else if (j == "LtSpice") x = CircuitSimulatorExporterModels::LTSPICE;
else if (j == "NL5") x = CircuitSimulatorExporterModels::NL5;
else if (j == "PLECS") x = CircuitSimulatorExporterModels::PLECS;
else { throw std::runtime_error("Input JSON does not conform to schema!"); }
}

Expand All @@ -428,6 +430,7 @@
case CircuitSimulatorExporterModels::NGSPICE: j = "NgSpice"; break;
case CircuitSimulatorExporterModels::LTSPICE: j = "LtSpice"; break;
case CircuitSimulatorExporterModels::NL5: j = "NL5"; break;
case CircuitSimulatorExporterModels::PLECS: j = "PLECS"; break;
default: throw std::runtime_error("Unexpected value in enumeration \"[object Object]\": " + std::to_string(static_cast<int>(x)));
}
}
Expand Down Expand Up @@ -525,6 +528,35 @@
std::string export_magnetic_as_symbol(Magnetic magnetic, std::optional<std::string> filePathOrFile = std::nullopt);
};

class CircuitSimulatorExporterPlecsModel : public CircuitSimulatorExporterModel {
public:
std::string programName = "PLECS";

Check warning on line 533 in src/processors/CircuitSimulatorInterface.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Declaration shadows a field "programName" in the outer scope.

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9Ks_sCLsiQJ0fnWj&open=AZ1H9Ks_sCLsiQJ0fnWj&pullRequest=57
double _modelSize = 400;
size_t _precision = 6;

CircuitSimulatorExporterPlecsModel() = default;

std::string export_magnetic_as_symbol(Magnetic magnetic, std::optional<std::string> filePathOrFile = std::nullopt);

Check warning on line 539 in src/processors/CircuitSimulatorInterface.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Annotate this function with "override" or "final".

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9Ks_sCLsiQJ0fnWk&open=AZ1H9Ks_sCLsiQJ0fnWk&pullRequest=57
std::string export_magnetic_as_subcircuit(Magnetic magnetic, double frequency = defaults.measurementFrequency, double temperature = defaults.ambientTemperature, std::optional<std::string> filePathOrFile = std::nullopt, CircuitSimulatorExporterCurveFittingModes mode = CircuitSimulatorExporterCurveFittingModes::LADDER);

Check warning on line 540 in src/processors/CircuitSimulatorInterface.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Annotate this function with "override" or "final".

See more on https://sonarcloud.io/project/issues?id=OpenMagnetics_MKF&issues=AZ1H9Ks_sCLsiQJ0fnWl&open=AZ1H9Ks_sCLsiQJ0fnWl&pullRequest=57

private:
std::string encode_init_commands(const std::string& plainText);
std::string emit_header(const std::string& name);
std::string emit_footer();
std::string emit_schematic_header();
std::string emit_schematic_footer();
std::string emit_magnetic_interface(const std::string& name, const std::string& turnsVar, int polarity, std::vector<int> position, const std::string& direction, bool flipped);
std::string emit_p_sat(const std::string& name, const std::string& areaVar, const std::string& lengthVar, const std::string& muRVar, const std::string& bSatVar, std::vector<int> position, const std::string& direction, bool flipped);
std::string emit_p_air(const std::string& name, const std::string& areaVar, const std::string& lengthVar, std::vector<int> position, const std::string& direction, bool flipped);
std::string emit_ac_voltage_source(const std::string& name, std::vector<int> position);
std::string emit_resistor(const std::string& name, const std::string& valueVar, std::vector<int> position);
std::string emit_scope(const std::string& name, std::vector<int> position);
std::string emit_probe(const std::string& name, std::vector<int> position, const std::vector<std::pair<std::string, std::string>>& probes);
std::string emit_magnetic_connection(const std::string& srcComponent, int srcTerminal, const std::string& dstComponent, int dstTerminal, std::vector<std::vector<int>> points = {});
std::string emit_wire_connection(const std::string& srcComponent, int srcTerminal, const std::string& dstComponent, int dstTerminal, std::vector<std::vector<int>> points = {});
std::string emit_signal_connection(const std::string& srcComponent, int srcTerminal, const std::string& dstComponent, int dstTerminal);
};

class CircuitSimulationReader {
public:
enum class DataType : int {
Expand Down
Loading
Loading