@tscircuit/core 0.0.1503 → 0.0.1505
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +686 -5
- package/dist/index.js +685 -102
- package/package.json +11 -9
package/dist/index.js
CHANGED
|
@@ -8,7 +8,13 @@ var __export = (target, all) => {
|
|
|
8
8
|
var components_exports = {};
|
|
9
9
|
__export(components_exports, {
|
|
10
10
|
Ammeter: () => Ammeter,
|
|
11
|
+
AnalogAcSweepSimulation: () => AnalogAcSweepSimulation,
|
|
12
|
+
AnalogAnalysisSimulation: () => AnalogAnalysisSimulation,
|
|
13
|
+
AnalogDcOperatingPointSimulation: () => AnalogDcOperatingPointSimulation,
|
|
14
|
+
AnalogDcSweepSimulation: () => AnalogDcSweepSimulation,
|
|
11
15
|
AnalogSimulation: () => AnalogSimulation,
|
|
16
|
+
AnalogSweepParameter: () => AnalogSweepParameter,
|
|
17
|
+
AnalogTransientSimulation: () => AnalogTransientSimulation,
|
|
12
18
|
AutoroutingPhase: () => AutoroutingPhase,
|
|
13
19
|
Battery: () => Battery,
|
|
14
20
|
Board: () => Board,
|
|
@@ -22666,7 +22672,6 @@ var Group_doInitialSchematicTraceRender = (group) => {
|
|
|
22666
22672
|
};
|
|
22667
22673
|
|
|
22668
22674
|
// lib/components/primitive-components/Group/Group_doInitialSimulationSpiceEngineRender.ts
|
|
22669
|
-
import { circuitJsonToSpice } from "circuit-json-to-spice";
|
|
22670
22675
|
import Debug13 from "debug";
|
|
22671
22676
|
|
|
22672
22677
|
// lib/utils/simulation/get-transient-voltage-graph-names-from-spice-netlist.ts
|
|
@@ -22739,6 +22744,176 @@ var getSpiceyEngine = () => {
|
|
|
22739
22744
|
};
|
|
22740
22745
|
};
|
|
22741
22746
|
|
|
22747
|
+
// lib/components/primitive-components/Group/isCurrentGraph.ts
|
|
22748
|
+
var isCurrentGraph = (element) => element.type === "simulation_transient_current_graph";
|
|
22749
|
+
|
|
22750
|
+
// lib/components/primitive-components/Group/isSimulationCurrentResult.ts
|
|
22751
|
+
var isSimulationCurrentResult = (circuitElement) => circuitElement.type === "simulation_dc_operating_point_current" || circuitElement.type === "simulation_dc_sweep_current_graph" || circuitElement.type === "simulation_ac_sweep_current_graph";
|
|
22752
|
+
|
|
22753
|
+
// lib/components/primitive-components/Group/isSimulationVoltageResult.ts
|
|
22754
|
+
var isSimulationVoltageResult = (circuitElement) => circuitElement.type === "simulation_dc_operating_point_voltage" || circuitElement.type === "simulation_dc_sweep_voltage_graph" || circuitElement.type === "simulation_ac_sweep_voltage_graph";
|
|
22755
|
+
|
|
22756
|
+
// lib/components/primitive-components/Group/isVoltageGraph.ts
|
|
22757
|
+
var isVoltageGraph = (element) => element.type === "simulation_transient_voltage_graph";
|
|
22758
|
+
|
|
22759
|
+
// lib/components/primitive-components/Group/isSimulationAnalysisResult.ts
|
|
22760
|
+
var isSimulationAnalysisResult = (circuitElement) => isVoltageGraph(circuitElement) || isCurrentGraph(circuitElement) || isSimulationVoltageResult(circuitElement) || isSimulationCurrentResult(circuitElement);
|
|
22761
|
+
|
|
22762
|
+
// lib/components/primitive-components/Group/attachSweepCoordinateToSimulationResult.ts
|
|
22763
|
+
var attachSweepCoordinateToSimulationResult = ({
|
|
22764
|
+
simulationResult,
|
|
22765
|
+
simulationParameterSweepCoordinate
|
|
22766
|
+
}) => {
|
|
22767
|
+
if (!simulationParameterSweepCoordinate || !isSimulationAnalysisResult(simulationResult)) {
|
|
22768
|
+
return simulationResult;
|
|
22769
|
+
}
|
|
22770
|
+
const simulationResultWithSweepCoordinate = { ...simulationResult };
|
|
22771
|
+
const simulationResultIdKey = `${simulationResultWithSweepCoordinate.type}_id`;
|
|
22772
|
+
Reflect.deleteProperty(
|
|
22773
|
+
simulationResultWithSweepCoordinate,
|
|
22774
|
+
simulationResultIdKey
|
|
22775
|
+
);
|
|
22776
|
+
simulationResultWithSweepCoordinate.simulation_parameter_sweep_coordinate = simulationParameterSweepCoordinate;
|
|
22777
|
+
return simulationResultWithSweepCoordinate;
|
|
22778
|
+
};
|
|
22779
|
+
|
|
22780
|
+
// lib/components/primitive-components/Group/createSimulationRuns.ts
|
|
22781
|
+
import { circuitJsonToSpice } from "circuit-json-to-spice";
|
|
22782
|
+
|
|
22783
|
+
// lib/components/primitive-components/Group/applyParameterSweepCoordinate.ts
|
|
22784
|
+
var getSourceComponentOrThrow = ({
|
|
22785
|
+
circuitJson,
|
|
22786
|
+
sourceComponentId,
|
|
22787
|
+
isMatchingSourceComponent
|
|
22788
|
+
}) => {
|
|
22789
|
+
const sourceComponent = circuitJson.find(
|
|
22790
|
+
(circuitElement) => isMatchingSourceComponent(circuitElement) && circuitElement.source_component_id === sourceComponentId
|
|
22791
|
+
);
|
|
22792
|
+
if (!sourceComponent) {
|
|
22793
|
+
throw new Error(`Parameter sweep target ${sourceComponentId} was not found`);
|
|
22794
|
+
}
|
|
22795
|
+
return sourceComponent;
|
|
22796
|
+
};
|
|
22797
|
+
var applyParameterSweepCoordinate = ({
|
|
22798
|
+
circuitJson,
|
|
22799
|
+
parameterSweep,
|
|
22800
|
+
simulationParameterSweepCoordinate
|
|
22801
|
+
}) => {
|
|
22802
|
+
const sweptCircuitJson = structuredClone(circuitJson);
|
|
22803
|
+
const parameterValue = simulationParameterSweepCoordinate.parameter_value;
|
|
22804
|
+
if (parameterSweep.parameter_type === "resistance") {
|
|
22805
|
+
const resistor = getSourceComponentOrThrow({
|
|
22806
|
+
circuitJson: sweptCircuitJson,
|
|
22807
|
+
sourceComponentId: parameterSweep.resistor_source_component_id,
|
|
22808
|
+
isMatchingSourceComponent: (circuitElement) => circuitElement.type === "source_component" && circuitElement.ftype === "simple_resistor"
|
|
22809
|
+
});
|
|
22810
|
+
resistor.resistance = parameterValue;
|
|
22811
|
+
return sweptCircuitJson;
|
|
22812
|
+
}
|
|
22813
|
+
if (parameterSweep.parameter_type === "capacitance") {
|
|
22814
|
+
const capacitor = getSourceComponentOrThrow({
|
|
22815
|
+
circuitJson: sweptCircuitJson,
|
|
22816
|
+
sourceComponentId: parameterSweep.capacitor_source_component_id,
|
|
22817
|
+
isMatchingSourceComponent: (circuitElement) => circuitElement.type === "source_component" && circuitElement.ftype === "simple_capacitor"
|
|
22818
|
+
});
|
|
22819
|
+
capacitor.capacitance = parameterValue;
|
|
22820
|
+
return sweptCircuitJson;
|
|
22821
|
+
}
|
|
22822
|
+
if (parameterSweep.parameter_type === "inductance") {
|
|
22823
|
+
const inductor = getSourceComponentOrThrow({
|
|
22824
|
+
circuitJson: sweptCircuitJson,
|
|
22825
|
+
sourceComponentId: parameterSweep.inductor_source_component_id,
|
|
22826
|
+
isMatchingSourceComponent: (circuitElement) => circuitElement.type === "source_component" && circuitElement.ftype === "simple_inductor"
|
|
22827
|
+
});
|
|
22828
|
+
inductor.inductance = parameterValue;
|
|
22829
|
+
return sweptCircuitJson;
|
|
22830
|
+
}
|
|
22831
|
+
if (parameterSweep.parameter_type === "voltage") {
|
|
22832
|
+
const groundNet = sweptCircuitJson.find(
|
|
22833
|
+
(circuitElement) => circuitElement.type === "source_net" && circuitElement.name.toUpperCase() === "GND"
|
|
22834
|
+
);
|
|
22835
|
+
if (!groundNet || groundNet.type !== "source_net") {
|
|
22836
|
+
throw new Error("A voltage parameter sweep requires a GND net");
|
|
22837
|
+
}
|
|
22838
|
+
const sweepVoltageSource = {
|
|
22839
|
+
type: "simulation_voltage_source",
|
|
22840
|
+
simulation_voltage_source_id: `simulation_voltage_source_${simulationParameterSweepCoordinate.simulation_parameter_sweep_id}_${simulationParameterSweepCoordinate.sweep_index}`,
|
|
22841
|
+
is_dc_source: true,
|
|
22842
|
+
positive_source_net_id: parameterSweep.source_net_id,
|
|
22843
|
+
negative_source_net_id: groundNet.source_net_id,
|
|
22844
|
+
voltage: parameterValue
|
|
22845
|
+
};
|
|
22846
|
+
sweptCircuitJson.push(sweepVoltageSource);
|
|
22847
|
+
return sweptCircuitJson;
|
|
22848
|
+
}
|
|
22849
|
+
if (parameterSweep.parameter_type === "current") {
|
|
22850
|
+
const currentSourcePortIds = new Set(
|
|
22851
|
+
sweptCircuitJson.filter(
|
|
22852
|
+
(circuitElement) => circuitElement.type === "source_port" && circuitElement.source_component_id === parameterSweep.current_source_component_id
|
|
22853
|
+
).map((sourcePort) => sourcePort.source_port_id)
|
|
22854
|
+
);
|
|
22855
|
+
const currentSource = sweptCircuitJson.find(
|
|
22856
|
+
(circuitElement) => circuitElement.type === "simulation_current_source" && (circuitElement.is_dc_source ? Boolean(
|
|
22857
|
+
circuitElement.positive_source_port_id && currentSourcePortIds.has(
|
|
22858
|
+
circuitElement.positive_source_port_id
|
|
22859
|
+
)
|
|
22860
|
+
) : Boolean(
|
|
22861
|
+
circuitElement.terminal1_source_port_id && currentSourcePortIds.has(
|
|
22862
|
+
circuitElement.terminal1_source_port_id
|
|
22863
|
+
)
|
|
22864
|
+
))
|
|
22865
|
+
);
|
|
22866
|
+
if (!currentSource) {
|
|
22867
|
+
throw new Error(
|
|
22868
|
+
`Current sweep target ${parameterSweep.current_source_component_id} has no simulation source`
|
|
22869
|
+
);
|
|
22870
|
+
}
|
|
22871
|
+
currentSource.current = parameterValue;
|
|
22872
|
+
return sweptCircuitJson;
|
|
22873
|
+
}
|
|
22874
|
+
throw new Error("Parameter sweep target is incomplete");
|
|
22875
|
+
};
|
|
22876
|
+
|
|
22877
|
+
// lib/components/primitive-components/Group/createSimulationRuns.ts
|
|
22878
|
+
var createSimulationRun = ({
|
|
22879
|
+
circuitJson,
|
|
22880
|
+
simulationParameterSweepCoordinate
|
|
22881
|
+
}) => {
|
|
22882
|
+
const spiceNetlist = circuitJsonToSpice(circuitJson);
|
|
22883
|
+
return {
|
|
22884
|
+
spiceNetlist,
|
|
22885
|
+
spiceString: spiceNetlist.toSpiceString(),
|
|
22886
|
+
simulationParameterSweepCoordinate
|
|
22887
|
+
};
|
|
22888
|
+
};
|
|
22889
|
+
var createSimulationRuns = ({
|
|
22890
|
+
circuitJson,
|
|
22891
|
+
simulationExperimentId
|
|
22892
|
+
}) => {
|
|
22893
|
+
const parameterSweep = circuitJson.find(
|
|
22894
|
+
(circuitElement) => circuitElement.type === "simulation_parameter_sweep" && circuitElement.simulation_experiment_id === simulationExperimentId
|
|
22895
|
+
);
|
|
22896
|
+
if (!parameterSweep) {
|
|
22897
|
+
return [createSimulationRun({ circuitJson })];
|
|
22898
|
+
}
|
|
22899
|
+
return parameterSweep.parameter_values.map((parameterValue, sweepIndex) => {
|
|
22900
|
+
const simulationParameterSweepCoordinate = {
|
|
22901
|
+
simulation_parameter_sweep_id: parameterSweep.simulation_parameter_sweep_id,
|
|
22902
|
+
sweep_index: sweepIndex,
|
|
22903
|
+
parameter_value: parameterValue,
|
|
22904
|
+
parameter_unit: parameterSweep.parameter_unit
|
|
22905
|
+
};
|
|
22906
|
+
return createSimulationRun({
|
|
22907
|
+
circuitJson: applyParameterSweepCoordinate({
|
|
22908
|
+
circuitJson,
|
|
22909
|
+
parameterSweep,
|
|
22910
|
+
simulationParameterSweepCoordinate
|
|
22911
|
+
}),
|
|
22912
|
+
simulationParameterSweepCoordinate
|
|
22913
|
+
});
|
|
22914
|
+
});
|
|
22915
|
+
};
|
|
22916
|
+
|
|
22742
22917
|
// lib/utils/simulation/parseSimulationGraphValue.ts
|
|
22743
22918
|
var SI_PREFIX_MULTIPLIERS = {
|
|
22744
22919
|
p: 1e-12,
|
|
@@ -22905,12 +23080,6 @@ var insertIndependentAxisScopeTraces = ({
|
|
|
22905
23080
|
// lib/components/primitive-components/Group/isCircuitElementInput.ts
|
|
22906
23081
|
var isCircuitElementInput = (element) => Boolean(element && typeof element === "object" && "type" in element);
|
|
22907
23082
|
|
|
22908
|
-
// lib/components/primitive-components/Group/isCurrentGraph.ts
|
|
22909
|
-
var isCurrentGraph = (element) => element.type === "simulation_transient_current_graph";
|
|
22910
|
-
|
|
22911
|
-
// lib/components/primitive-components/Group/isVoltageGraph.ts
|
|
22912
|
-
var isVoltageGraph = (element) => element.type === "simulation_transient_voltage_graph";
|
|
22913
|
-
|
|
22914
23083
|
// lib/components/primitive-components/Group/Group_doInitialSimulationSpiceEngineRender.ts
|
|
22915
23084
|
var debug11 = Debug13("tscircuit:core:Group_doInitialSimulationSpiceEngineRender");
|
|
22916
23085
|
var getCircuitJsonForAnalogSimulation = ({
|
|
@@ -22920,10 +23089,14 @@ var getCircuitJsonForAnalogSimulation = ({
|
|
|
22920
23089
|
ammeters
|
|
22921
23090
|
}) => {
|
|
22922
23091
|
const voltageProbeIds = new Set(
|
|
22923
|
-
voltageProbes.map((
|
|
23092
|
+
voltageProbes.map((voltageProbe) => voltageProbe.simulation_voltage_probe_id).filter(
|
|
23093
|
+
(simulationVoltageProbeId) => Boolean(simulationVoltageProbeId)
|
|
23094
|
+
)
|
|
22924
23095
|
);
|
|
22925
23096
|
const currentProbeIds = new Set(
|
|
22926
|
-
ammeters.map((ammeter) => ammeter.simulation_current_probe_id).filter(
|
|
23097
|
+
ammeters.map((ammeter) => ammeter.simulation_current_probe_id).filter(
|
|
23098
|
+
(simulationCurrentProbeId) => Boolean(simulationCurrentProbeId)
|
|
23099
|
+
)
|
|
22927
23100
|
);
|
|
22928
23101
|
return circuitJson.filter((element) => {
|
|
22929
23102
|
if (element.type === "simulation_experiment") {
|
|
@@ -22935,6 +23108,9 @@ var getCircuitJsonForAnalogSimulation = ({
|
|
|
22935
23108
|
if (element.type === "simulation_current_probe") {
|
|
22936
23109
|
return currentProbeIds.has(element.simulation_current_probe_id);
|
|
22937
23110
|
}
|
|
23111
|
+
if (element.type === "simulation_parameter_sweep") {
|
|
23112
|
+
return element.simulation_experiment_id === simulationExperimentId;
|
|
23113
|
+
}
|
|
22938
23114
|
if (element.type === "simulation_oscilloscope_trace") {
|
|
22939
23115
|
if (element.simulation_voltage_probe_id) {
|
|
22940
23116
|
return voltageProbeIds.has(element.simulation_voltage_probe_id);
|
|
@@ -22943,7 +23119,7 @@ var getCircuitJsonForAnalogSimulation = ({
|
|
|
22943
23119
|
return currentProbeIds.has(element.simulation_current_probe_id);
|
|
22944
23120
|
}
|
|
22945
23121
|
}
|
|
22946
|
-
if (element.type === "simulation_transient_voltage_graph" || element.type === "simulation_transient_current_graph" || element.type === "simulation_unknown_experiment_error") {
|
|
23122
|
+
if (element.type === "simulation_transient_voltage_graph" || element.type === "simulation_transient_current_graph" || element.type === "simulation_dc_operating_point_voltage" || element.type === "simulation_dc_operating_point_current" || element.type === "simulation_dc_sweep_voltage_graph" || element.type === "simulation_dc_sweep_current_graph" || element.type === "simulation_ac_sweep_voltage_graph" || element.type === "simulation_ac_sweep_current_graph" || element.type === "simulation_unknown_experiment_error") {
|
|
22947
23123
|
return false;
|
|
22948
23124
|
}
|
|
22949
23125
|
return true;
|
|
@@ -22953,15 +23129,23 @@ function Group_doInitialSimulationSpiceEngineRender(group) {
|
|
|
22953
23129
|
if (!group.isSubcircuit) return;
|
|
22954
23130
|
const { root } = group;
|
|
22955
23131
|
if (!root) return;
|
|
22956
|
-
const
|
|
22957
|
-
|
|
23132
|
+
const analogSimulations = [
|
|
23133
|
+
...group.selectAll("analogsimulation"),
|
|
23134
|
+
...group.selectAll("analogtransientsimulation"),
|
|
23135
|
+
...group.selectAll(
|
|
23136
|
+
"analogdcoperatingpointsimulation"
|
|
23137
|
+
),
|
|
23138
|
+
...group.selectAll("analogdcsweepsimulation"),
|
|
23139
|
+
...group.selectAll("analogacsweepsimulation")
|
|
23140
|
+
];
|
|
23141
|
+
if (analogSimulations.length === 0) return;
|
|
22958
23142
|
resetSimulationColorState();
|
|
22959
23143
|
const spiceEngineMap = { ...root.platform?.spiceEngineMap };
|
|
22960
23144
|
if (!spiceEngineMap.spicey) {
|
|
22961
23145
|
spiceEngineMap.spicey = getSpiceyEngine();
|
|
22962
23146
|
}
|
|
22963
|
-
for (const
|
|
22964
|
-
const simulationExperimentId =
|
|
23147
|
+
for (const analogSimulation of analogSimulations) {
|
|
23148
|
+
const simulationExperimentId = analogSimulation.simulation_experiment_id;
|
|
22965
23149
|
if (!simulationExperimentId) {
|
|
22966
23150
|
debug11("No simulation experiment id found, skipping simulation");
|
|
22967
23151
|
continue;
|
|
@@ -22973,7 +23157,7 @@ function Group_doInitialSimulationSpiceEngineRender(group) {
|
|
|
22973
23157
|
debug11("No simulation experiment found, skipping simulation");
|
|
22974
23158
|
continue;
|
|
22975
23159
|
}
|
|
22976
|
-
const simulationScope =
|
|
23160
|
+
const simulationScope = analogSimulation.getGroup() ?? group;
|
|
22977
23161
|
const voltageProbes = simulationScope.selectAll("voltageprobe");
|
|
22978
23162
|
const ammeters = simulationScope.selectAll("ammeter");
|
|
22979
23163
|
const circuitJson = getCircuitJsonForAnalogSimulation({
|
|
@@ -22982,13 +23166,16 @@ function Group_doInitialSimulationSpiceEngineRender(group) {
|
|
|
22982
23166
|
voltageProbes,
|
|
22983
23167
|
ammeters
|
|
22984
23168
|
});
|
|
22985
|
-
let
|
|
22986
|
-
let spiceNetlist;
|
|
23169
|
+
let simulationRuns;
|
|
22987
23170
|
try {
|
|
22988
|
-
|
|
22989
|
-
|
|
22990
|
-
|
|
22991
|
-
|
|
23171
|
+
simulationRuns = createSimulationRuns({
|
|
23172
|
+
circuitJson,
|
|
23173
|
+
simulationExperimentId
|
|
23174
|
+
});
|
|
23175
|
+
debug11(
|
|
23176
|
+
`Generated ${simulationRuns.length} SPICE run(s):
|
|
23177
|
+
${simulationRuns.map((simulationRun) => simulationRun.spiceString).join("\n")}`
|
|
23178
|
+
);
|
|
22992
23179
|
} catch (error) {
|
|
22993
23180
|
debug11(`Failed to convert circuit JSON to SPICE: ${error}`);
|
|
22994
23181
|
root.db.simulation_unknown_experiment_error.insert({
|
|
@@ -22998,15 +23185,15 @@ ${spiceString}`);
|
|
|
22998
23185
|
});
|
|
22999
23186
|
continue;
|
|
23000
23187
|
}
|
|
23001
|
-
const
|
|
23002
|
-
const
|
|
23188
|
+
const voltageProbeByGraphName = /* @__PURE__ */ new Map();
|
|
23189
|
+
const voltageProbeById = /* @__PURE__ */ new Map();
|
|
23003
23190
|
const graphDisplayOverridesByProbeId = /* @__PURE__ */ new Map();
|
|
23004
23191
|
for (const probe of voltageProbes) {
|
|
23005
23192
|
if (probe.finalProbeName) {
|
|
23006
|
-
|
|
23193
|
+
voltageProbeByGraphName.set(probe.finalProbeName, probe);
|
|
23007
23194
|
}
|
|
23008
23195
|
if (probe.simulation_voltage_probe_id) {
|
|
23009
|
-
|
|
23196
|
+
voltageProbeById.set(probe.simulation_voltage_probe_id, probe);
|
|
23010
23197
|
graphDisplayOverridesByProbeId.set(
|
|
23011
23198
|
probe.simulation_voltage_probe_id,
|
|
23012
23199
|
getVoltageProbeGraphDisplayOverrides(probe)
|
|
@@ -23022,33 +23209,36 @@ ${spiceString}`);
|
|
|
23022
23209
|
}
|
|
23023
23210
|
}
|
|
23024
23211
|
const scopedCurrentProbeIds = new Set(
|
|
23025
|
-
ammeters.map((ammeter) => ammeter.simulation_current_probe_id).filter(
|
|
23212
|
+
ammeters.map((ammeter) => ammeter.simulation_current_probe_id).filter(
|
|
23213
|
+
(simulationCurrentProbeId) => Boolean(simulationCurrentProbeId)
|
|
23214
|
+
)
|
|
23026
23215
|
);
|
|
23027
|
-
const
|
|
23028
|
-
const
|
|
23216
|
+
const currentProbeById = /* @__PURE__ */ new Map();
|
|
23217
|
+
const currentProbeByName = /* @__PURE__ */ new Map();
|
|
23029
23218
|
for (const probe of root.db.simulation_current_probe.list().filter(
|
|
23030
23219
|
(probe2) => scopedCurrentProbeIds.has(probe2.simulation_current_probe_id)
|
|
23031
23220
|
)) {
|
|
23032
|
-
|
|
23221
|
+
currentProbeById.set(probe.simulation_current_probe_id, probe);
|
|
23033
23222
|
if (probe.name !== void 0) {
|
|
23034
|
-
|
|
23223
|
+
currentProbeByName.set(probe.name, probe);
|
|
23035
23224
|
}
|
|
23036
23225
|
}
|
|
23037
23226
|
const orderedSimulationProbes = root.db.simulation_voltage_probe.list().filter(
|
|
23038
|
-
(probe) =>
|
|
23227
|
+
(probe) => voltageProbeById.has(probe.simulation_voltage_probe_id)
|
|
23039
23228
|
);
|
|
23040
|
-
const
|
|
23229
|
+
const firstSpiceNetlist = simulationRuns[0]?.spiceNetlist;
|
|
23230
|
+
const graphNamesFromNetlist = firstSpiceNetlist ? getTransientVoltageGraphNamesFromSpiceNetlist(firstSpiceNetlist) : [];
|
|
23041
23231
|
if (graphNamesFromNetlist.length === orderedSimulationProbes.length) {
|
|
23042
23232
|
for (const [
|
|
23043
|
-
|
|
23233
|
+
simulationProbeIndex,
|
|
23044
23234
|
simulationProbe
|
|
23045
23235
|
] of orderedSimulationProbes.entries()) {
|
|
23046
|
-
const probe =
|
|
23236
|
+
const probe = voltageProbeById.get(
|
|
23047
23237
|
simulationProbe.simulation_voltage_probe_id
|
|
23048
23238
|
);
|
|
23049
|
-
const graphName = graphNamesFromNetlist[
|
|
23239
|
+
const graphName = graphNamesFromNetlist[simulationProbeIndex];
|
|
23050
23240
|
if (probe && graphName) {
|
|
23051
|
-
|
|
23241
|
+
voltageProbeByGraphName.set(graphName, probe);
|
|
23052
23242
|
}
|
|
23053
23243
|
}
|
|
23054
23244
|
} else {
|
|
@@ -23056,12 +23246,14 @@ ${spiceString}`);
|
|
|
23056
23246
|
`Skipping probe-to-graph order mapping because counts differ: probes=${orderedSimulationProbes.length} graphNames=${graphNamesFromNetlist.length}`
|
|
23057
23247
|
);
|
|
23058
23248
|
}
|
|
23059
|
-
const engineName =
|
|
23249
|
+
const engineName = analogSimulation.getSpiceEngineName() ?? "spicey";
|
|
23060
23250
|
const spiceEngine = spiceEngineMap[engineName];
|
|
23061
23251
|
if (!spiceEngine) {
|
|
23062
23252
|
throw new Error(
|
|
23063
23253
|
`SPICE engine "${engineName}" not found in platform config. Available engines: ${JSON.stringify(
|
|
23064
|
-
Object.keys(spiceEngineMap).filter(
|
|
23254
|
+
Object.keys(spiceEngineMap).filter(
|
|
23255
|
+
(spiceEngineName) => spiceEngineName !== "spicey"
|
|
23256
|
+
)
|
|
23065
23257
|
)}`
|
|
23066
23258
|
);
|
|
23067
23259
|
}
|
|
@@ -23071,51 +23263,90 @@ ${spiceString}`);
|
|
|
23071
23263
|
);
|
|
23072
23264
|
group._queueAsyncEffect(effectId, async () => {
|
|
23073
23265
|
try {
|
|
23074
|
-
debug11(`Running simulation with engine: ${engineName}`);
|
|
23075
|
-
const result = await spiceEngine.simulate(spiceString);
|
|
23076
|
-
debug11(
|
|
23077
|
-
`Simulation completed, received ${result.simulationResultCircuitJson.length} elements`
|
|
23078
|
-
);
|
|
23079
23266
|
const insertedVoltageGraphs = [];
|
|
23080
23267
|
const insertedCurrentGraphs = [];
|
|
23081
|
-
for (const
|
|
23082
|
-
|
|
23083
|
-
|
|
23084
|
-
|
|
23085
|
-
|
|
23086
|
-
|
|
23087
|
-
|
|
23088
|
-
|
|
23089
|
-
|
|
23090
|
-
if (
|
|
23091
|
-
|
|
23092
|
-
|
|
23093
|
-
}
|
|
23094
|
-
}
|
|
23095
|
-
if (isCurrentGraph(element)) {
|
|
23096
|
-
element.simulation_experiment_id = simulationExperiment.simulation_experiment_id;
|
|
23097
|
-
const probeMatch = (element.source_probe_id ? currentProbesById.get(element.source_probe_id) : void 0) ?? (element.name ? currentProbesByName.get(element.name) : void 0);
|
|
23098
|
-
if (probeMatch) {
|
|
23099
|
-
element.color = probeMatch.color;
|
|
23100
|
-
element.source_probe_id = probeMatch.simulation_current_probe_id;
|
|
23268
|
+
for (const simulationRun of simulationRuns) {
|
|
23269
|
+
debug11(`Running simulation with engine: ${engineName}`);
|
|
23270
|
+
const simulationResult = await spiceEngine.simulate(
|
|
23271
|
+
simulationRun.spiceString
|
|
23272
|
+
);
|
|
23273
|
+
debug11(
|
|
23274
|
+
`Simulation completed, received ${simulationResult.simulationResultCircuitJson.length} elements`
|
|
23275
|
+
);
|
|
23276
|
+
for (const simulationResultCircuitElement of simulationResult.simulationResultCircuitJson) {
|
|
23277
|
+
if (!isCircuitElementInput(simulationResultCircuitElement)) {
|
|
23278
|
+
debug11("Skipping invalid simulation result element");
|
|
23279
|
+
continue;
|
|
23101
23280
|
}
|
|
23102
|
-
|
|
23103
|
-
|
|
23104
|
-
|
|
23105
|
-
insertedVoltageGraphs.push({
|
|
23106
|
-
type: "voltage",
|
|
23107
|
-
graph: insertedElement
|
|
23108
|
-
});
|
|
23109
|
-
}
|
|
23110
|
-
if (isCurrentGraph(insertedElement)) {
|
|
23111
|
-
insertedCurrentGraphs.push({
|
|
23112
|
-
type: "current",
|
|
23113
|
-
graph: insertedElement
|
|
23281
|
+
const simulationResultWithSweepCoordinate = attachSweepCoordinateToSimulationResult({
|
|
23282
|
+
simulationResult: simulationResultCircuitElement,
|
|
23283
|
+
simulationParameterSweepCoordinate: simulationRun.simulationParameterSweepCoordinate
|
|
23114
23284
|
});
|
|
23285
|
+
if (isVoltageGraph(simulationResultWithSweepCoordinate)) {
|
|
23286
|
+
simulationResultWithSweepCoordinate.simulation_experiment_id = simulationExperiment.simulation_experiment_id;
|
|
23287
|
+
const probeMatch = simulationResultWithSweepCoordinate.name ? voltageProbeByGraphName.get(
|
|
23288
|
+
simulationResultWithSweepCoordinate.name
|
|
23289
|
+
) : void 0;
|
|
23290
|
+
if (probeMatch) {
|
|
23291
|
+
simulationResultWithSweepCoordinate.color = probeMatch.color ?? void 0;
|
|
23292
|
+
simulationResultWithSweepCoordinate.source_probe_id = probeMatch.simulation_voltage_probe_id ?? void 0;
|
|
23293
|
+
}
|
|
23294
|
+
} else if (isSimulationVoltageResult(simulationResultWithSweepCoordinate)) {
|
|
23295
|
+
simulationResultWithSweepCoordinate.simulation_experiment_id = simulationExperiment.simulation_experiment_id;
|
|
23296
|
+
const probeMatch = voltageProbeById.get(
|
|
23297
|
+
simulationResultWithSweepCoordinate.simulation_voltage_probe_id
|
|
23298
|
+
) ?? (simulationResultWithSweepCoordinate.name ? voltageProbeByGraphName.get(
|
|
23299
|
+
simulationResultWithSweepCoordinate.name
|
|
23300
|
+
) : void 0);
|
|
23301
|
+
if (probeMatch?.simulation_voltage_probe_id) {
|
|
23302
|
+
simulationResultWithSweepCoordinate.color = probeMatch.color ?? void 0;
|
|
23303
|
+
simulationResultWithSweepCoordinate.simulation_voltage_probe_id = probeMatch.simulation_voltage_probe_id;
|
|
23304
|
+
}
|
|
23305
|
+
}
|
|
23306
|
+
if (isCurrentGraph(simulationResultWithSweepCoordinate)) {
|
|
23307
|
+
simulationResultWithSweepCoordinate.simulation_experiment_id = simulationExperiment.simulation_experiment_id;
|
|
23308
|
+
const probeMatch = (simulationResultWithSweepCoordinate.source_probe_id ? currentProbeById.get(
|
|
23309
|
+
simulationResultWithSweepCoordinate.source_probe_id
|
|
23310
|
+
) : void 0) ?? (simulationResultWithSweepCoordinate.name ? currentProbeByName.get(
|
|
23311
|
+
simulationResultWithSweepCoordinate.name
|
|
23312
|
+
) : void 0);
|
|
23313
|
+
if (probeMatch) {
|
|
23314
|
+
simulationResultWithSweepCoordinate.color = probeMatch.color;
|
|
23315
|
+
simulationResultWithSweepCoordinate.source_probe_id = probeMatch.simulation_current_probe_id;
|
|
23316
|
+
}
|
|
23317
|
+
} else if (isSimulationCurrentResult(simulationResultWithSweepCoordinate)) {
|
|
23318
|
+
simulationResultWithSweepCoordinate.simulation_experiment_id = simulationExperiment.simulation_experiment_id;
|
|
23319
|
+
const probeMatch = currentProbeById.get(
|
|
23320
|
+
simulationResultWithSweepCoordinate.simulation_current_probe_id
|
|
23321
|
+
) ?? (simulationResultWithSweepCoordinate.name ? currentProbeByName.get(
|
|
23322
|
+
simulationResultWithSweepCoordinate.name
|
|
23323
|
+
) : void 0);
|
|
23324
|
+
if (probeMatch) {
|
|
23325
|
+
simulationResultWithSweepCoordinate.color = probeMatch.color;
|
|
23326
|
+
simulationResultWithSweepCoordinate.simulation_current_probe_id = probeMatch.simulation_current_probe_id;
|
|
23327
|
+
}
|
|
23328
|
+
}
|
|
23329
|
+
const insertedSimulationResult = root.db.insert(
|
|
23330
|
+
simulationResultWithSweepCoordinate
|
|
23331
|
+
);
|
|
23332
|
+
if (isVoltageGraph(insertedSimulationResult)) {
|
|
23333
|
+
insertedVoltageGraphs.push({
|
|
23334
|
+
type: "voltage",
|
|
23335
|
+
graph: insertedSimulationResult
|
|
23336
|
+
});
|
|
23337
|
+
}
|
|
23338
|
+
if (isCurrentGraph(insertedSimulationResult)) {
|
|
23339
|
+
insertedCurrentGraphs.push({
|
|
23340
|
+
type: "current",
|
|
23341
|
+
graph: insertedSimulationResult
|
|
23342
|
+
});
|
|
23343
|
+
}
|
|
23344
|
+
debug11(
|
|
23345
|
+
`Inserted ${simulationResultWithSweepCoordinate.type} into database`
|
|
23346
|
+
);
|
|
23115
23347
|
}
|
|
23116
|
-
debug11(`Inserted ${element.type} into database`);
|
|
23117
23348
|
}
|
|
23118
|
-
if (
|
|
23349
|
+
if (analogSimulation.usesIndependentGraphAxes()) {
|
|
23119
23350
|
insertIndependentAxisScopeTraces({
|
|
23120
23351
|
db: root.db,
|
|
23121
23352
|
graphs: [...insertedVoltageGraphs, ...insertedCurrentGraphs],
|
|
@@ -23423,7 +23654,7 @@ function Group_getRoutingPhasePlans(group) {
|
|
|
23423
23654
|
var package_default = {
|
|
23424
23655
|
name: "@tscircuit/core",
|
|
23425
23656
|
type: "module",
|
|
23426
|
-
version: "0.0.
|
|
23657
|
+
version: "0.0.1504",
|
|
23427
23658
|
types: "dist/index.d.ts",
|
|
23428
23659
|
main: "dist/index.js",
|
|
23429
23660
|
module: "dist/index.js",
|
|
@@ -23459,11 +23690,11 @@ var package_default = {
|
|
|
23459
23690
|
"@tscircuit/breakout-point-solver": "github:tscircuit/breakout-point-solver#bac9629",
|
|
23460
23691
|
"@tscircuit/capacity-autorouter": "^0.0.710",
|
|
23461
23692
|
"@tscircuit/checks": "0.0.145",
|
|
23462
|
-
"@tscircuit/circuit-json-util": "^0.0.
|
|
23693
|
+
"@tscircuit/circuit-json-util": "^0.0.101",
|
|
23463
23694
|
"@tscircuit/common": "^0.0.20",
|
|
23464
23695
|
"@tscircuit/copper-pour-solver": "0.0.39",
|
|
23465
23696
|
"@tscircuit/create-fdm-enclosure": "0.0.3",
|
|
23466
|
-
"@tscircuit/footprinter": "^0.0.
|
|
23697
|
+
"@tscircuit/footprinter": "^0.0.387",
|
|
23467
23698
|
"@tscircuit/image-utils": "^0.0.8",
|
|
23468
23699
|
"@tscircuit/infer-cable-insertion-point": "^0.0.2",
|
|
23469
23700
|
"@tscircuit/infgrid-ijump-astar": "^0.0.35",
|
|
@@ -23473,8 +23704,8 @@ var package_default = {
|
|
|
23473
23704
|
"@tscircuit/matchpack": "^0.0.48",
|
|
23474
23705
|
"@tscircuit/math-utils": "^0.0.36",
|
|
23475
23706
|
"@tscircuit/miniflex": "^0.0.4",
|
|
23476
|
-
"@tscircuit/ngspice-spice-engine": "^0.0.
|
|
23477
|
-
"@tscircuit/props": "^0.0.
|
|
23707
|
+
"@tscircuit/ngspice-spice-engine": "^0.0.20",
|
|
23708
|
+
"@tscircuit/props": "^0.0.592",
|
|
23478
23709
|
"@tscircuit/schematic-match-adapt": "^0.0.18",
|
|
23479
23710
|
"@tscircuit/schematic-trace-solver": "^0.0.108",
|
|
23480
23711
|
"@tscircuit/solver-utils": "^0.0.16",
|
|
@@ -23488,12 +23719,12 @@ var package_default = {
|
|
|
23488
23719
|
"bun-match-svg": "0.0.12",
|
|
23489
23720
|
"calculate-elbow": "^0.0.12",
|
|
23490
23721
|
"chokidar-cli": "^3.0.0",
|
|
23491
|
-
"circuit-json": "^0.0.
|
|
23722
|
+
"circuit-json": "^0.0.454",
|
|
23492
23723
|
"circuit-json-to-bpc": "^0.0.13",
|
|
23493
23724
|
"circuit-json-to-connectivity-map": "^0.0.23",
|
|
23494
23725
|
"circuit-json-to-gltf": "^0.0.107",
|
|
23495
|
-
"circuit-json-to-spice": "^0.0.
|
|
23496
|
-
"circuit-to-svg": "^0.0.
|
|
23726
|
+
"circuit-json-to-spice": "^0.0.45",
|
|
23727
|
+
"circuit-to-svg": "^0.0.393",
|
|
23497
23728
|
concurrently: "^9.1.2",
|
|
23498
23729
|
"connectivity-map": "^1.0.0",
|
|
23499
23730
|
debug: "^4.3.6",
|
|
@@ -23510,7 +23741,7 @@ var package_default = {
|
|
|
23510
23741
|
react: "^19.1.0",
|
|
23511
23742
|
"react-dom": "^19.1.0",
|
|
23512
23743
|
"schematic-symbols": "^0.0.233",
|
|
23513
|
-
spicets: "^0.0.
|
|
23744
|
+
spicets: "^0.0.4",
|
|
23514
23745
|
spicey: "^0.0.14",
|
|
23515
23746
|
"stack-svgs": "^0.0.1",
|
|
23516
23747
|
"ts-expect": "^1.3.0",
|
|
@@ -23531,7 +23762,9 @@ var package_default = {
|
|
|
23531
23762
|
"@tscircuit/matchpack": "*",
|
|
23532
23763
|
"circuit-json": "*",
|
|
23533
23764
|
"circuit-json-to-connectivity-map": "*",
|
|
23765
|
+
"circuit-json-to-spice": "*",
|
|
23534
23766
|
"schematic-symbols": "*",
|
|
23767
|
+
spicets: "*",
|
|
23535
23768
|
typescript: "^5.0.0"
|
|
23536
23769
|
},
|
|
23537
23770
|
dependencies: {
|
|
@@ -29543,6 +29776,7 @@ var PowerSource = class extends NormalComponent3 {
|
|
|
29543
29776
|
import { voltageSourceProps } from "@tscircuit/props";
|
|
29544
29777
|
import { formatSiUnit as formatSiUnit5 } from "format-si-unit";
|
|
29545
29778
|
var VoltageSource = class extends NormalComponent3 {
|
|
29779
|
+
simulation_voltage_source_id = null;
|
|
29546
29780
|
get config() {
|
|
29547
29781
|
const isSquare = this.props.waveShape === "square";
|
|
29548
29782
|
return {
|
|
@@ -29619,11 +29853,10 @@ var VoltageSource = class extends NormalComponent3 {
|
|
|
29619
29853
|
const { _parsedProps: props } = this;
|
|
29620
29854
|
const terminal1Port = this.portMap.terminal1;
|
|
29621
29855
|
const terminal2Port = this.portMap.terminal2;
|
|
29622
|
-
db.simulation_voltage_source.insert({
|
|
29623
|
-
type: "simulation_voltage_source",
|
|
29856
|
+
const simulationVoltageSource = db.simulation_voltage_source.insert({
|
|
29624
29857
|
is_dc_source: false,
|
|
29625
|
-
terminal1_source_port_id: terminal1Port.source_port_id,
|
|
29626
|
-
terminal2_source_port_id: terminal2Port.source_port_id,
|
|
29858
|
+
terminal1_source_port_id: terminal1Port.source_port_id ?? void 0,
|
|
29859
|
+
terminal2_source_port_id: terminal2Port.source_port_id ?? void 0,
|
|
29627
29860
|
voltage: props.voltage,
|
|
29628
29861
|
frequency: props.frequency,
|
|
29629
29862
|
peak_to_peak_voltage: props.peakToPeakVoltage,
|
|
@@ -29634,8 +29867,11 @@ var VoltageSource = class extends NormalComponent3 {
|
|
|
29634
29867
|
rise_time: props.riseTime,
|
|
29635
29868
|
fall_time: props.fallTime,
|
|
29636
29869
|
pulse_width: props.pulseWidth,
|
|
29637
|
-
period: props.period
|
|
29870
|
+
period: props.period,
|
|
29871
|
+
ac_magnitude: props.acMagnitude,
|
|
29872
|
+
ac_phase: props.acPhase
|
|
29638
29873
|
});
|
|
29874
|
+
this.simulation_voltage_source_id = simulationVoltageSource.simulation_voltage_source_id;
|
|
29639
29875
|
}
|
|
29640
29876
|
terminal1 = this.portMap.terminal1;
|
|
29641
29877
|
terminal2 = this.portMap.terminal2;
|
|
@@ -29645,6 +29881,7 @@ var VoltageSource = class extends NormalComponent3 {
|
|
|
29645
29881
|
import { currentSourceProps } from "@tscircuit/props";
|
|
29646
29882
|
import { formatSiUnit as formatSiUnit6 } from "format-si-unit";
|
|
29647
29883
|
var CurrentSource = class extends NormalComponent3 {
|
|
29884
|
+
simulation_current_source_id = null;
|
|
29648
29885
|
get config() {
|
|
29649
29886
|
const symbolName = "current_source";
|
|
29650
29887
|
return {
|
|
@@ -29717,32 +29954,36 @@ var CurrentSource = class extends NormalComponent3 {
|
|
|
29717
29954
|
doInitialSimulationRender() {
|
|
29718
29955
|
const { db } = this.root;
|
|
29719
29956
|
const { _parsedProps: props } = this;
|
|
29720
|
-
const isAc = props.frequency !== void 0 || props.peakToPeakCurrent !== void 0 || props.waveShape !== void 0;
|
|
29957
|
+
const isAc = props.frequency !== void 0 || props.peakToPeakCurrent !== void 0 || props.waveShape !== void 0 || props.acMagnitude !== void 0 || props.acPhase !== void 0;
|
|
29721
29958
|
const posPort = this.portMap.pos;
|
|
29722
29959
|
const negPort = this.portMap.neg;
|
|
29723
29960
|
if (isAc) {
|
|
29724
|
-
db.simulation_current_source.insert({
|
|
29725
|
-
type: "simulation_current_source",
|
|
29961
|
+
const simulationCurrentSource = db.simulation_current_source.insert({
|
|
29726
29962
|
is_dc_source: false,
|
|
29727
|
-
terminal1_source_port_id: posPort.source_port_id,
|
|
29728
|
-
terminal2_source_port_id: negPort.source_port_id,
|
|
29963
|
+
terminal1_source_port_id: posPort.source_port_id ?? void 0,
|
|
29964
|
+
terminal2_source_port_id: negPort.source_port_id ?? void 0,
|
|
29729
29965
|
current: props.current,
|
|
29730
29966
|
// DC offset
|
|
29731
29967
|
frequency: props.frequency,
|
|
29732
29968
|
peak_to_peak_current: props.peakToPeakCurrent,
|
|
29733
29969
|
wave_shape: props.waveShape,
|
|
29734
29970
|
phase: props.phase,
|
|
29735
|
-
duty_cycle: props.dutyCycle
|
|
29971
|
+
duty_cycle: props.dutyCycle,
|
|
29972
|
+
ac_magnitude: props.acMagnitude,
|
|
29973
|
+
ac_phase: props.acPhase
|
|
29736
29974
|
});
|
|
29975
|
+
this.simulation_current_source_id = simulationCurrentSource.simulation_current_source_id;
|
|
29737
29976
|
} else {
|
|
29738
29977
|
if (props.current === void 0) return;
|
|
29739
|
-
db.simulation_current_source.insert({
|
|
29740
|
-
type: "simulation_current_source",
|
|
29978
|
+
const simulationCurrentSource = db.simulation_current_source.insert({
|
|
29741
29979
|
is_dc_source: true,
|
|
29742
|
-
positive_source_port_id: posPort.source_port_id,
|
|
29743
|
-
negative_source_port_id: negPort.source_port_id,
|
|
29744
|
-
current: props.current
|
|
29980
|
+
positive_source_port_id: posPort.source_port_id ?? void 0,
|
|
29981
|
+
negative_source_port_id: negPort.source_port_id ?? void 0,
|
|
29982
|
+
current: props.current,
|
|
29983
|
+
ac_magnitude: props.acMagnitude,
|
|
29984
|
+
ac_phase: props.acPhase
|
|
29745
29985
|
});
|
|
29986
|
+
this.simulation_current_source_id = simulationCurrentSource.simulation_current_source_id;
|
|
29746
29987
|
}
|
|
29747
29988
|
}
|
|
29748
29989
|
pos = this.portMap.pos;
|
|
@@ -34109,6 +34350,12 @@ var AnalogSimulation = class extends PrimitiveComponent2 {
|
|
|
34109
34350
|
zodProps: analogSimulationProps
|
|
34110
34351
|
};
|
|
34111
34352
|
}
|
|
34353
|
+
getSpiceEngineName() {
|
|
34354
|
+
return this._parsedProps.spiceEngine;
|
|
34355
|
+
}
|
|
34356
|
+
usesIndependentGraphAxes() {
|
|
34357
|
+
return this._parsedProps.graphIndependentAxes === true;
|
|
34358
|
+
}
|
|
34112
34359
|
doInitialSimulationRender() {
|
|
34113
34360
|
const { db } = this.root;
|
|
34114
34361
|
const { duration, name, startTime, timePerStep, spiceOptions } = this._parsedProps;
|
|
@@ -34126,6 +34373,316 @@ var AnalogSimulation = class extends PrimitiveComponent2 {
|
|
|
34126
34373
|
}
|
|
34127
34374
|
};
|
|
34128
34375
|
|
|
34376
|
+
// lib/components/primitive-components/AnalogAnalysisSimulation.ts
|
|
34377
|
+
var AnalogAnalysisSimulation = class extends PrimitiveComponent2 {
|
|
34378
|
+
simulation_experiment_id = null;
|
|
34379
|
+
getSpiceEngineName() {
|
|
34380
|
+
return typeof this.props.spiceEngine === "string" ? this.props.spiceEngine : void 0;
|
|
34381
|
+
}
|
|
34382
|
+
usesIndependentGraphAxes() {
|
|
34383
|
+
return this.props.graphIndependentAxes === true;
|
|
34384
|
+
}
|
|
34385
|
+
getOrCreateSimulationExperiment() {
|
|
34386
|
+
if (this.simulation_experiment_id) {
|
|
34387
|
+
return this.root?.db.simulation_experiment.get(
|
|
34388
|
+
this.simulation_experiment_id
|
|
34389
|
+
) ?? null;
|
|
34390
|
+
}
|
|
34391
|
+
const sweepParameterCount = this.children.filter(
|
|
34392
|
+
(child) => child.componentName === "AnalogSweepParameter"
|
|
34393
|
+
).length;
|
|
34394
|
+
if (sweepParameterCount > 1) {
|
|
34395
|
+
this.renderError(
|
|
34396
|
+
"An analog simulation can contain at most one sweep parameter."
|
|
34397
|
+
);
|
|
34398
|
+
return null;
|
|
34399
|
+
}
|
|
34400
|
+
const simulationExperiment = this.insertSimulationExperiment();
|
|
34401
|
+
this.simulation_experiment_id = simulationExperiment?.simulation_experiment_id ?? null;
|
|
34402
|
+
return simulationExperiment;
|
|
34403
|
+
}
|
|
34404
|
+
doInitialSimulationRender() {
|
|
34405
|
+
this.getOrCreateSimulationExperiment();
|
|
34406
|
+
}
|
|
34407
|
+
};
|
|
34408
|
+
|
|
34409
|
+
// lib/components/primitive-components/AnalogTransientSimulation.ts
|
|
34410
|
+
import { analogTransientSimulationProps } from "@tscircuit/props";
|
|
34411
|
+
var AnalogTransientSimulation = class extends AnalogAnalysisSimulation {
|
|
34412
|
+
get config() {
|
|
34413
|
+
return {
|
|
34414
|
+
componentName: "AnalogTransientSimulation",
|
|
34415
|
+
zodProps: analogTransientSimulationProps
|
|
34416
|
+
};
|
|
34417
|
+
}
|
|
34418
|
+
insertSimulationExperiment() {
|
|
34419
|
+
const { db } = this.root;
|
|
34420
|
+
const { duration, name, startTime, timePerStep, spiceOptions } = this._parsedProps;
|
|
34421
|
+
return db.simulation_experiment.insert({
|
|
34422
|
+
name: name ?? "spice_transient_analysis",
|
|
34423
|
+
experiment_type: "spice_transient_analysis",
|
|
34424
|
+
end_time_ms: duration,
|
|
34425
|
+
start_time_ms: startTime,
|
|
34426
|
+
time_per_step: timePerStep,
|
|
34427
|
+
spice_options: spiceOptions
|
|
34428
|
+
});
|
|
34429
|
+
}
|
|
34430
|
+
};
|
|
34431
|
+
|
|
34432
|
+
// lib/components/primitive-components/AnalogDcOperatingPointSimulation.ts
|
|
34433
|
+
import { analogDcOperatingPointSimulationProps } from "@tscircuit/props";
|
|
34434
|
+
var AnalogDcOperatingPointSimulation = class extends AnalogAnalysisSimulation {
|
|
34435
|
+
get config() {
|
|
34436
|
+
return {
|
|
34437
|
+
componentName: "AnalogDcOperatingPointSimulation",
|
|
34438
|
+
zodProps: analogDcOperatingPointSimulationProps
|
|
34439
|
+
};
|
|
34440
|
+
}
|
|
34441
|
+
insertSimulationExperiment() {
|
|
34442
|
+
const { name, spiceOptions } = this._parsedProps;
|
|
34443
|
+
return this.root.db.simulation_experiment.insert({
|
|
34444
|
+
name: name ?? "spice_dc_operating_point",
|
|
34445
|
+
experiment_type: "spice_dc_operating_point",
|
|
34446
|
+
spice_options: spiceOptions
|
|
34447
|
+
});
|
|
34448
|
+
}
|
|
34449
|
+
};
|
|
34450
|
+
|
|
34451
|
+
// lib/components/primitive-components/AnalogDcSweepSimulation.ts
|
|
34452
|
+
import { analogDcSweepSimulationProps } from "@tscircuit/props";
|
|
34453
|
+
var AnalogDcSweepSimulation = class extends AnalogAnalysisSimulation {
|
|
34454
|
+
get config() {
|
|
34455
|
+
return {
|
|
34456
|
+
componentName: "AnalogDcSweepSimulation",
|
|
34457
|
+
zodProps: analogDcSweepSimulationProps
|
|
34458
|
+
};
|
|
34459
|
+
}
|
|
34460
|
+
insertSimulationExperiment() {
|
|
34461
|
+
const {
|
|
34462
|
+
name,
|
|
34463
|
+
spiceOptions,
|
|
34464
|
+
sweepSource,
|
|
34465
|
+
sweepStart,
|
|
34466
|
+
sweepStop,
|
|
34467
|
+
sweepStep
|
|
34468
|
+
} = this._parsedProps;
|
|
34469
|
+
const simulationScope = this.getGroup() ?? this.getSubcircuit();
|
|
34470
|
+
const sweepSourceComponent = simulationScope?.selectOne(sweepSource);
|
|
34471
|
+
let dcSweepSourceFields;
|
|
34472
|
+
if (sweepSourceComponent instanceof VoltageSource) {
|
|
34473
|
+
sweepSourceComponent.runRenderPhase("SimulationRender");
|
|
34474
|
+
const simulationVoltageSourceId = sweepSourceComponent.simulation_voltage_source_id;
|
|
34475
|
+
if (!simulationVoltageSourceId) {
|
|
34476
|
+
this.renderError(
|
|
34477
|
+
`DC sweep source "${sweepSource}" must resolve to one voltage or current source.`
|
|
34478
|
+
);
|
|
34479
|
+
return null;
|
|
34480
|
+
}
|
|
34481
|
+
dcSweepSourceFields = {
|
|
34482
|
+
dc_sweep_voltage_source_id: simulationVoltageSourceId,
|
|
34483
|
+
dc_sweep_unit: "V"
|
|
34484
|
+
};
|
|
34485
|
+
} else if (sweepSourceComponent instanceof CurrentSource) {
|
|
34486
|
+
sweepSourceComponent.runRenderPhase("SimulationRender");
|
|
34487
|
+
const simulationCurrentSourceId = sweepSourceComponent.simulation_current_source_id;
|
|
34488
|
+
if (!simulationCurrentSourceId) {
|
|
34489
|
+
this.renderError(
|
|
34490
|
+
`DC sweep source "${sweepSource}" must resolve to one voltage or current source.`
|
|
34491
|
+
);
|
|
34492
|
+
return null;
|
|
34493
|
+
}
|
|
34494
|
+
dcSweepSourceFields = {
|
|
34495
|
+
dc_sweep_current_source_id: simulationCurrentSourceId,
|
|
34496
|
+
dc_sweep_unit: "A"
|
|
34497
|
+
};
|
|
34498
|
+
} else {
|
|
34499
|
+
this.renderError(
|
|
34500
|
+
`DC sweep source "${sweepSource}" must resolve to one voltage or current source.`
|
|
34501
|
+
);
|
|
34502
|
+
return null;
|
|
34503
|
+
}
|
|
34504
|
+
return this.root.db.simulation_experiment.insert({
|
|
34505
|
+
name: name ?? "spice_dc_sweep",
|
|
34506
|
+
experiment_type: "spice_dc_sweep",
|
|
34507
|
+
spice_options: spiceOptions,
|
|
34508
|
+
...dcSweepSourceFields,
|
|
34509
|
+
dc_sweep_start: sweepStart,
|
|
34510
|
+
dc_sweep_stop: sweepStop,
|
|
34511
|
+
dc_sweep_step: sweepStep
|
|
34512
|
+
});
|
|
34513
|
+
}
|
|
34514
|
+
};
|
|
34515
|
+
|
|
34516
|
+
// lib/components/primitive-components/AnalogAcSweepSimulation.ts
|
|
34517
|
+
import { analogAcSweepSimulationProps } from "@tscircuit/props";
|
|
34518
|
+
var AnalogAcSweepSimulation = class extends AnalogAnalysisSimulation {
|
|
34519
|
+
get config() {
|
|
34520
|
+
return {
|
|
34521
|
+
componentName: "AnalogAcSweepSimulation",
|
|
34522
|
+
zodProps: analogAcSweepSimulationProps
|
|
34523
|
+
};
|
|
34524
|
+
}
|
|
34525
|
+
insertSimulationExperiment() {
|
|
34526
|
+
const {
|
|
34527
|
+
name,
|
|
34528
|
+
spiceOptions,
|
|
34529
|
+
sweepType,
|
|
34530
|
+
samplesPerInterval,
|
|
34531
|
+
sampleCount,
|
|
34532
|
+
startFrequency,
|
|
34533
|
+
stopFrequency
|
|
34534
|
+
} = this._parsedProps;
|
|
34535
|
+
return this.root.db.simulation_experiment.insert({
|
|
34536
|
+
name: name ?? "spice_ac_analysis",
|
|
34537
|
+
experiment_type: "spice_ac_analysis",
|
|
34538
|
+
spice_options: spiceOptions,
|
|
34539
|
+
ac_sweep_type: sweepType,
|
|
34540
|
+
ac_samples_per_interval: samplesPerInterval,
|
|
34541
|
+
ac_sample_count: sampleCount,
|
|
34542
|
+
ac_start_frequency_hz: startFrequency,
|
|
34543
|
+
ac_stop_frequency_hz: stopFrequency
|
|
34544
|
+
});
|
|
34545
|
+
}
|
|
34546
|
+
};
|
|
34547
|
+
|
|
34548
|
+
// lib/components/primitive-components/AnalogSweepParameter.ts
|
|
34549
|
+
import { analogSweepParameterProps } from "@tscircuit/props";
|
|
34550
|
+
|
|
34551
|
+
// lib/components/primitive-components/AnalogSweepParameter_doInitialSimulationRender.ts
|
|
34552
|
+
var parameterUnits = {
|
|
34553
|
+
resistance: "\u03A9",
|
|
34554
|
+
capacitance: "F",
|
|
34555
|
+
inductance: "H",
|
|
34556
|
+
voltage: "V",
|
|
34557
|
+
current: "A"
|
|
34558
|
+
};
|
|
34559
|
+
var isParameterSweepCoordinateInRange = ({
|
|
34560
|
+
parameterSweepCoordinate,
|
|
34561
|
+
stop,
|
|
34562
|
+
step
|
|
34563
|
+
}) => {
|
|
34564
|
+
const tolerance = Math.abs(step) * 1e-9;
|
|
34565
|
+
return step > 0 ? parameterSweepCoordinate <= stop + tolerance : parameterSweepCoordinate >= stop - tolerance;
|
|
34566
|
+
};
|
|
34567
|
+
var getGeneratedParameterSweepCoordinates = ({
|
|
34568
|
+
start,
|
|
34569
|
+
stop,
|
|
34570
|
+
step
|
|
34571
|
+
}) => {
|
|
34572
|
+
const parameterSweepCoordinates = [];
|
|
34573
|
+
for (let parameterSweepCoordinate = start; isParameterSweepCoordinateInRange({
|
|
34574
|
+
parameterSweepCoordinate,
|
|
34575
|
+
stop,
|
|
34576
|
+
step
|
|
34577
|
+
}); parameterSweepCoordinate = start + parameterSweepCoordinates.length * step) {
|
|
34578
|
+
parameterSweepCoordinates.push(parameterSweepCoordinate);
|
|
34579
|
+
if (parameterSweepCoordinates.length > 1e6) {
|
|
34580
|
+
throw new Error("Parameter sweep exceeds 1,000,000 points");
|
|
34581
|
+
}
|
|
34582
|
+
}
|
|
34583
|
+
return parameterSweepCoordinates;
|
|
34584
|
+
};
|
|
34585
|
+
var getParameterSweepTargetSelector = (props) => {
|
|
34586
|
+
if (props.parameterType === "resistance") return props.resistorRef;
|
|
34587
|
+
if (props.parameterType === "capacitance") return props.capacitorRef;
|
|
34588
|
+
if (props.parameterType === "inductance") return props.inductorRef;
|
|
34589
|
+
if (props.parameterType === "voltage") return props.net;
|
|
34590
|
+
return props.currentSourceRef;
|
|
34591
|
+
};
|
|
34592
|
+
var AnalogSweepParameter_doInitialSimulationRender = (analogSweepParameter) => {
|
|
34593
|
+
if (!(analogSweepParameter.parent instanceof AnalogAnalysisSimulation)) {
|
|
34594
|
+
analogSweepParameter.renderError(
|
|
34595
|
+
"analog.sweepparameter must be nested directly in an analog simulation."
|
|
34596
|
+
);
|
|
34597
|
+
return;
|
|
34598
|
+
}
|
|
34599
|
+
const simulationExperiment = analogSweepParameter.parent.getOrCreateSimulationExperiment();
|
|
34600
|
+
if (!simulationExperiment) return;
|
|
34601
|
+
const props = analogSweepParameter._parsedProps;
|
|
34602
|
+
const parameterSweepCoordinates = props.values ?? getGeneratedParameterSweepCoordinates({
|
|
34603
|
+
start: props.start,
|
|
34604
|
+
stop: props.stop,
|
|
34605
|
+
step: props.step
|
|
34606
|
+
});
|
|
34607
|
+
const simulationScope = analogSweepParameter.parent.getGroup() ?? analogSweepParameter.parent.getSubcircuit();
|
|
34608
|
+
const targetSelector = getParameterSweepTargetSelector(props);
|
|
34609
|
+
const parameterUnit = parameterUnits[props.parameterType];
|
|
34610
|
+
const simulationParameterSweepTable = analogSweepParameter.root.db.simulation_parameter_sweep;
|
|
34611
|
+
const simulationParameterSweepFields = {
|
|
34612
|
+
simulation_experiment_id: simulationExperiment.simulation_experiment_id,
|
|
34613
|
+
name: props.name,
|
|
34614
|
+
parameter_type: props.parameterType,
|
|
34615
|
+
parameter_values: parameterSweepCoordinates,
|
|
34616
|
+
parameter_unit: parameterUnit
|
|
34617
|
+
};
|
|
34618
|
+
let simulationParameterSweepId;
|
|
34619
|
+
if (props.parameterType === "voltage") {
|
|
34620
|
+
const sweepNet = simulationScope?.selectOne(targetSelector, {
|
|
34621
|
+
type: "net"
|
|
34622
|
+
});
|
|
34623
|
+
if (!sweepNet?.source_net_id) {
|
|
34624
|
+
analogSweepParameter.renderError(
|
|
34625
|
+
`Voltage sweep net "${targetSelector}" could not be resolved.`
|
|
34626
|
+
);
|
|
34627
|
+
return;
|
|
34628
|
+
}
|
|
34629
|
+
simulationParameterSweepId = simulationParameterSweepTable.insert({
|
|
34630
|
+
...simulationParameterSweepFields,
|
|
34631
|
+
parameter_type: "voltage",
|
|
34632
|
+
source_net_id: sweepNet.source_net_id
|
|
34633
|
+
}).simulation_parameter_sweep_id;
|
|
34634
|
+
} else {
|
|
34635
|
+
const sweepTarget = simulationScope?.selectOne(targetSelector);
|
|
34636
|
+
const sourceComponentId = sweepTarget?.source_component_id;
|
|
34637
|
+
if (!sourceComponentId) {
|
|
34638
|
+
analogSweepParameter.renderError(
|
|
34639
|
+
`Parameter sweep target "${targetSelector}" could not be resolved.`
|
|
34640
|
+
);
|
|
34641
|
+
return;
|
|
34642
|
+
}
|
|
34643
|
+
if (props.parameterType === "resistance") {
|
|
34644
|
+
simulationParameterSweepId = simulationParameterSweepTable.insert({
|
|
34645
|
+
...simulationParameterSweepFields,
|
|
34646
|
+
parameter_type: "resistance",
|
|
34647
|
+
resistor_source_component_id: sourceComponentId
|
|
34648
|
+
}).simulation_parameter_sweep_id;
|
|
34649
|
+
} else if (props.parameterType === "capacitance") {
|
|
34650
|
+
simulationParameterSweepId = simulationParameterSweepTable.insert({
|
|
34651
|
+
...simulationParameterSweepFields,
|
|
34652
|
+
parameter_type: "capacitance",
|
|
34653
|
+
capacitor_source_component_id: sourceComponentId
|
|
34654
|
+
}).simulation_parameter_sweep_id;
|
|
34655
|
+
} else if (props.parameterType === "inductance") {
|
|
34656
|
+
simulationParameterSweepId = simulationParameterSweepTable.insert({
|
|
34657
|
+
...simulationParameterSweepFields,
|
|
34658
|
+
parameter_type: "inductance",
|
|
34659
|
+
inductor_source_component_id: sourceComponentId
|
|
34660
|
+
}).simulation_parameter_sweep_id;
|
|
34661
|
+
} else {
|
|
34662
|
+
simulationParameterSweepId = simulationParameterSweepTable.insert({
|
|
34663
|
+
...simulationParameterSweepFields,
|
|
34664
|
+
parameter_type: "current",
|
|
34665
|
+
current_source_component_id: sourceComponentId
|
|
34666
|
+
}).simulation_parameter_sweep_id;
|
|
34667
|
+
}
|
|
34668
|
+
}
|
|
34669
|
+
analogSweepParameter.simulation_parameter_sweep_id = simulationParameterSweepId;
|
|
34670
|
+
};
|
|
34671
|
+
|
|
34672
|
+
// lib/components/primitive-components/AnalogSweepParameter.ts
|
|
34673
|
+
var AnalogSweepParameter = class extends PrimitiveComponent2 {
|
|
34674
|
+
simulation_parameter_sweep_id = null;
|
|
34675
|
+
get config() {
|
|
34676
|
+
return {
|
|
34677
|
+
componentName: "AnalogSweepParameter",
|
|
34678
|
+
zodProps: analogSweepParameterProps
|
|
34679
|
+
};
|
|
34680
|
+
}
|
|
34681
|
+
doInitialSimulationRender() {
|
|
34682
|
+
AnalogSweepParameter_doInitialSimulationRender(this);
|
|
34683
|
+
}
|
|
34684
|
+
};
|
|
34685
|
+
|
|
34129
34686
|
// lib/components/primitive-components/VoltageProbe.ts
|
|
34130
34687
|
import { voltageProbeProps } from "@tscircuit/props";
|
|
34131
34688
|
|
|
@@ -34508,6 +35065,25 @@ var createNamespacedElement = (hostType) => {
|
|
|
34508
35065
|
return Component2;
|
|
34509
35066
|
};
|
|
34510
35067
|
|
|
35068
|
+
// lib/namespaced-elements/analog.ts
|
|
35069
|
+
var analog = {
|
|
35070
|
+
transientsimulation: createNamespacedElement(
|
|
35071
|
+
"analogtransientsimulation"
|
|
35072
|
+
),
|
|
35073
|
+
dcoperatingpointsimulation: createNamespacedElement(
|
|
35074
|
+
"analogdcoperatingpointsimulation"
|
|
35075
|
+
),
|
|
35076
|
+
dcsweepsimulation: createNamespacedElement(
|
|
35077
|
+
"analogdcsweepsimulation"
|
|
35078
|
+
),
|
|
35079
|
+
acsweepsimulation: createNamespacedElement(
|
|
35080
|
+
"analogacsweepsimulation"
|
|
35081
|
+
),
|
|
35082
|
+
sweepparameter: createNamespacedElement(
|
|
35083
|
+
"analogsweepparameter"
|
|
35084
|
+
)
|
|
35085
|
+
};
|
|
35086
|
+
|
|
34511
35087
|
// lib/namespaced-elements/enclosure.ts
|
|
34512
35088
|
var EnclosureFdmBoxElement = createNamespacedElement("enclosure.fdm.box");
|
|
34513
35089
|
var enclosure = {
|
|
@@ -34752,7 +35328,13 @@ extendCatalogue({
|
|
|
34752
35328
|
});
|
|
34753
35329
|
export {
|
|
34754
35330
|
Ammeter,
|
|
35331
|
+
AnalogAcSweepSimulation,
|
|
35332
|
+
AnalogAnalysisSimulation,
|
|
35333
|
+
AnalogDcOperatingPointSimulation,
|
|
35334
|
+
AnalogDcSweepSimulation,
|
|
34755
35335
|
AnalogSimulation,
|
|
35336
|
+
AnalogSweepParameter,
|
|
35337
|
+
AnalogTransientSimulation,
|
|
34756
35338
|
AutoroutingPhase,
|
|
34757
35339
|
Battery,
|
|
34758
35340
|
Board,
|
|
@@ -34856,6 +35438,7 @@ export {
|
|
|
34856
35438
|
Via,
|
|
34857
35439
|
VoltageProbe,
|
|
34858
35440
|
VoltageSource,
|
|
35441
|
+
analog,
|
|
34859
35442
|
applyEditEvents,
|
|
34860
35443
|
applyEditEventsToManualEditsFile,
|
|
34861
35444
|
applyPcbEditEventsToManualEditsFile,
|