/// <summary> /// Generates a new voltage controlled current source: GName. /// </summary> /// <param name="name">Name of generated voltage controlled current source.</param> /// <param name="parameters">Parameters for current source.</param> /// <param name="context">Reading context.</param> /// <returns> /// A new instance of voltage controlled current source. /// </returns> protected IEntity GenerateVoltageControlledCurrentSource(string name, ParameterCollection parameters, ICircuitContext context) { if (parameters.Count == 5 && parameters.IsValueString(0) && parameters.IsValueString(1) && parameters.IsValueString(2) && parameters.IsValueString(3) && parameters.IsValueString(4)) { var vccs = new VoltageControlledCurrentSource(name); context.CreateNodes(vccs, parameters); context.SetParameter(vccs, "gain", parameters.Get(4)); return(vccs); } else { if (parameters.Count == 3 && parameters[0] is PointParameter pp1 && pp1.Values.Count() == 2 && parameters[1] is PointParameter pp2 && pp2.Values.Count() == 2) { var vccsNodes = new ParameterCollection(new List <Parameter>()); vccsNodes.Add(pp1.Values.Items[0]); vccsNodes.Add(pp1.Values.Items[1]); vccsNodes.Add(pp2.Values.Items[0]); vccsNodes.Add(pp2.Values.Items[1]); var vccs = new VoltageControlledCurrentSource(name); context.CreateNodes(vccs, vccsNodes); context.SetParameter(vccs, "gain", parameters.Get(2)); return(vccs); }
public override SpiceSharp.Components.Component Generate(string name, string originalName, string type, ParameterCollection parameters, ICircuitContext context) { var losslessLine = new LosslessTransmissionLine(name); context.CreateNodes(losslessLine, parameters); parameters = parameters.Skip(4); foreach (Parameter parameter in parameters) { if (parameter is AssignmentParameter ap) { var paramName = ap.Name.ToLower(); if (paramName == "z0" || paramName == "zo") { context.SetParameter(losslessLine, "z0", ap.Value); } else if (paramName == "f") { context.SetParameter(losslessLine, "f", ap.Value); } else if (paramName == "td") { context.SetParameter(losslessLine, "td", ap.Value); } else if (paramName == "reltol") { context.SetParameter(losslessLine, "reltol", ap.Value); } else if (paramName == "abstol") { context.SetParameter(losslessLine, "abstol", ap.Value); } else { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Invalid parameter: {parameter.Image}", parameter.LineInfo)); } } } return(losslessLine); }
public override IEntity Generate(string name, string originalName, string type, ParameterCollection parameters, ICircuitContext context) { if (parameters.Count > 7 || parameters.Count < 5) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, "Wrong parameter count for voltage delay", parameters.LineInfo)); return(null); } var vd = new VoltageDelay(name); context.CreateNodes(vd, parameters); parameters = parameters.Skip(4); foreach (Parameter parameter in parameters) { if (parameter is AssignmentParameter ap) { var paramName = ap.Name.ToLower(); if (paramName == "reltol") { context.SetParameter(vd, "reltol", ap.Value); } else if (paramName == "abstol") { context.SetParameter(vd, "abstol", ap.Value); } else { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Wrong parameter {paramName} for voltage delay", parameters.LineInfo)); return(null); } } else { context.SetParameter(vd, "delay", parameter.Image); } } return(vd); }
/// <summary> /// Generates a new mutual inductance. /// </summary> /// <param name="name">The name of generated mutual inductance.</param> /// <param name="parameters">Parameters and pins for mutual inductance.</param> /// <param name="context">Reading context.</param> /// <returns> /// A new instance of mutual inductance. /// </returns> protected SpiceSharp.Components.Component GenerateMut(string name, ParameterCollection parameters, ICircuitContext context) { var mut = new MutualInductance(name); switch (parameters.Count) { case 0: context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Inductor name expected for mutual inductance \"{name}\"", parameters.LineInfo)); return(null); case 1: context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Inductor name expected", parameters.LineInfo)); return(null); case 2: context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Coupling factor expected", parameters.LineInfo)); return(null); } if (!(parameters[0] is SingleParameter)) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Component name expected", parameters.LineInfo)); return(null); } if (!(parameters[1] is SingleParameter)) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Component name expected", parameters.LineInfo)); return(null); } mut.InductorName1 = parameters.Get(0).Image; mut.InductorName2 = parameters.Get(1).Image; context.SetParameter(mut, "k", parameters.Get(2)); return(mut); }
/// <summary> /// Generates a new inductor. /// </summary> /// <param name="name">Name of inductor to generate.</param> /// <param name="parameters">Parameters and pins for inductor.</param> /// <param name="context">Reading context.</param> /// <returns> /// A new instance of inductor. /// </returns> protected SpiceSharp.Components.Component GenerateInd(string name, ParameterCollection parameters, ICircuitContext context) { if (parameters.Count != 3) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Inductor expects 3 parameters/pins", parameters.LineInfo)); return(null); } var inductor = new Inductor(name); context.CreateNodes(inductor, parameters); context.SetParameter(inductor, "inductance", parameters.Get(2)); return(inductor); }
/// <summary> /// Generates a new current controlled current source: FName. /// </summary> /// <param name="name">Name of generated current controlled current source.</param> /// <param name="parameters">Parameters for current source.</param> /// <param name="context">Reading context.</param> /// <returns> /// A new instance of current controlled current source. /// </returns> protected IEntity GenerateCurrentControlledCurrentSource(string name, ParameterCollection parameters, ICircuitContext context) { if (parameters.Count == 4 && parameters.IsValueString(0) && parameters.IsValueString(1) && parameters.IsValueString(2) && parameters[2].Image.ToLower() != "value" && parameters.IsValueString(3)) { var cccs = new CurrentControlledCurrentSource(name); context.CreateNodes(cccs, parameters); cccs.ControllingSource = context.NameGenerator.GenerateObjectName(parameters.Get(2).Image); context.SetParameter(cccs, "gain", parameters.Get(3)); return(cccs); } else { return(CreateCustomCurrentSource(name, parameters, context, false)); } }
protected void SetParameters(ICircuitContext context, Entity entity, ParameterCollection parameters, bool onload) { foreach (Parameter parameter in parameters) { if (parameter is AssignmentParameter ap) { try { context.SetParameter(entity, ap.Name, ap.Value, true, onload); } catch (Exception) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Problem with setting parameter: {parameter.Image}", parameter.LineInfo)); } } else { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Unsupported parameter: {parameter.Image}", parameter.LineInfo)); } } }
public IEntity Generate(string componentIdentifier, string originalName, string type, ParameterCollection parameters, ICircuitContext context) { if (parameters.Count < 4) { throw new System.Exception("Model expected"); } JFET jfet = new JFET(componentIdentifier); context.CreateNodes(jfet, parameters); context.SimulationPreparations.ExecuteActionBeforeSetup((simulation) => { context.ModelsRegistry.SetModel( jfet, simulation, parameters.Get(3), $"Could not find model {parameters.Get(3)} for JFET {originalName}", (Context.Models.Model model) => jfet.Model = model.Name, context.Result); }); // Read the rest of the parameters for (int i = 3; i < parameters.Count; i++) { if (parameters[i] is WordParameter w) { if (w.Image.ToLower() == "off") { jfet.SetParameter("off", true); } } if (parameters[i] is AssignmentParameter asg) { if (asg.Name.ToLower() == "ic") { if (asg.Value.Length == 2) { context.SetParameter(jfet, "ic-vds", asg.Values[0]); context.SetParameter(jfet, "ic-vgs", asg.Values[1]); } if (asg.Value.Length == 1) { context.SetParameter(jfet, "ic-vds", asg.Values[0]); } } else if (asg.Name.ToLower() == "temp") { context.SetParameter(jfet, "temp", asg.Value); } else if (asg.Name.ToLower() == "area") { context.SetParameter(jfet, "area", asg.Value); } else { throw new System.Exception("Unknown parameter: " + asg.Name); } } if (parameters[i] is ValueParameter || parameters[i] is ExpressionParameter) { context.SetParameter(jfet, "area", parameters[i].Image); } } return(jfet); }
/// <summary> /// Generates a new capacitor. /// </summary> /// <param name="name">Name of capacitor to generate.</param> /// <param name="parameters">Parameters and pins for capacitor.</param> /// <param name="context">Reading context.</param> /// <returns> /// A new instance of capacitor. /// </returns> protected SpiceSharp.Components.Component GenerateCap(string name, ParameterCollection parameters, ICircuitContext context) { var capacitor = new Capacitor(name); context.CreateNodes(capacitor, parameters); // Get TC Parameter Parameter tcParameter = parameters.FirstOrDefault( p => p is AssignmentParameter ap && ap.Name.Equals( "tc", context.CaseSensitivity.IsEntityParameterNameCaseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase)); if (tcParameter != null) { parameters.Remove(tcParameter); } bool modelBased = false; if (parameters.Count == 3) { // CXXXXXXX N1 N2 VALUE if (parameters[2] is ExpressionParameter || parameters[2] is ValueParameter) { context.SetParameter(capacitor, "capacitance", parameters.Get(2)); } else { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Wrong parameter value for capacitance", parameters.LineInfo)); return(null); } } else { // CXXXXXXX N1 N2 <VALUE> <MNAME> <L=LENGTH> <W=WIDTH> <IC=VAL> // Examples: // CMOD 3 7 CMODEL L = 10u W = 1u // CMOD 3 7 CMODEL L = 10u W = 1u IC=1 // CMOD 3 7 1.3 IC=1 if (parameters[2] is ExpressionParameter || parameters[2] is ValueParameter) { context.SetParameter(capacitor, "capacitance", parameters.Get(2)); } else { context.SimulationPreparations.ExecuteActionBeforeSetup((simulation) => { context.ModelsRegistry.SetModel( capacitor, simulation, parameters.Get(2), $"Could not find model {parameters.Get(2)} for capacitor {name}", (CapacitorModel model) => capacitor.Model = model.Name, context.Result); }); modelBased = true; } SetParameters(context, capacitor, parameters.Skip(3), true); if (modelBased) { var bp = capacitor.ParameterSets[typeof(SpiceSharp.Components.CapacitorBehaviors.BaseParameters)] as SpiceSharp.Components.CapacitorBehaviors.BaseParameters; if (bp == null || !bp.Length.Given) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"L needs to be specified", parameters.LineInfo)); return(null); } } } if (tcParameter != null) { var tcParameterAssignment = tcParameter as AssignmentParameter; if (tcParameterAssignment == null) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"TC needs to be assignment parameter", parameters.LineInfo)); return(null); } if (modelBased) { var model = context.ModelsRegistry.FindModel <CapacitorModel>(parameters.Get(2).Image); if (tcParameterAssignment.Values.Count == 2) { context.SetParameter(model, "tc1", tcParameterAssignment.Values[0]); context.SetParameter(model, "tc2", tcParameterAssignment.Values[1]); } else { context.SetParameter(model, "tc1", tcParameterAssignment.Value); } context.Result.AddEntity(model); capacitor.Model = model.Name; } else { var model = new CapacitorModel(capacitor.Name + "_default_model"); if (tcParameterAssignment.Values.Count == 2) { context.SetParameter(model, "tc1", tcParameterAssignment.Values[0]); context.SetParameter(model, "tc2", tcParameterAssignment.Values[1]); } else { context.SetParameter(model, "tc1", tcParameterAssignment.Value); } context.ModelsRegistry.RegisterModelInstance(model); context.Result.AddEntity(model); capacitor.Model = model.Name; } } return(capacitor); }
protected void SetSourceParameters( string name, ParameterCollection parameters, ICircuitContext context, Component component) { var originalParameters = parameters; parameters = parameters.Skip(VoltageSource.VoltageSourcePinCount); var acParameter = parameters.FirstOrDefault(p => p.Image.ToLower() == "ac"); if (acParameter != null) { int acParameterIndex = parameters.IndexOf(acParameter); if (acParameterIndex != parameters.Count - 1) { var acParameterValue = parameters.Get(acParameterIndex + 1); context.SetParameter(component, "acmag", acParameterValue); if (acParameterIndex + 1 != parameters.Count - 1) { // Check first if next parameter is waveform var acPhaseCandidate = parameters[acParameterIndex + 2].Image; if (parameters[acParameterIndex + 2] is SingleParameter && !context.WaveformReader.Supports(acPhaseCandidate, context) && acPhaseCandidate.ToLower() != "dc") { var acPhaseParameterValue = parameters.Get(acParameterIndex + 2); context.SetParameter(component, "acphase", acPhaseParameterValue); parameters.RemoveAt(acParameterIndex + 2); } } parameters.RemoveAt(acParameterIndex + 1); } parameters.RemoveAt(acParameterIndex); } // 2. Set DC var dcParameter = parameters.FirstOrDefault(p => p.Image.ToLower() == "dc"); if (dcParameter != null) { int dcParameterIndex = parameters.IndexOf(dcParameter); if (dcParameterIndex != parameters.Count - 1) { var dcParameterValue = parameters.Get(dcParameterIndex + 1); context.SetParameter(component, "dc", dcParameterValue); parameters.RemoveAt(dcParameterIndex + 1); } parameters.RemoveAt(dcParameterIndex); } else { if (parameters.Count > 0 && parameters[0] is SingleParameter sp && !context.WaveformReader.Supports(sp.Image, context) && parameters[0].Image.ToLower() != "value") { context.SetParameter(component, "dc", sp); parameters.RemoveAt(0); } } // 3. Set up waveform if (parameters.Count > 0) { var firstParameter = parameters[0]; if (firstParameter is BracketParameter bp) { if (context.WaveformReader.Supports(bp.Name, context)) { component.SetParameter("waveform", context.WaveformReader.Generate(bp.Name, bp.Parameters, context)); } else { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Unsupported waveform: {bp.Name}", bp.LineInfo)); } } else { if (firstParameter is WordParameter wp && wp.Image.ToLower() != "value") { if (context.WaveformReader.Supports(wp.Image, context)) { component.SetParameter("waveform", context.WaveformReader.Generate(wp.Image, parameters.Skip(1), context)); } else { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Unsupported waveform: {wp}", wp.LineInfo)); } } } if (firstParameter is AssignmentParameter ap && ap.Name.ToLower() == "value") { context.SetParameter(component, "dc", ap.Value); } if (parameters.Count >= 2 && parameters[0].Image.ToLower() == "value" && parameters[1] is SingleParameter) { context.SetParameter(component, "dc", parameters[1].Image); } } context.CreateNodes(component, originalParameters); }
/// <summary> /// Generate resistor. /// </summary> /// <param name="name">Name of resistor to generate.</param> /// <param name="parameters">Parameters and pins for resistor.</param> /// <param name="context">Reading context.</param> /// <returns> /// A new instance of resistor. /// </returns> protected IEntity GenerateRes(string name, ParameterCollection parameters, ICircuitContext context) { if (parameters.Count == 3) { var evalContext = context.Evaluator.GetEvaluationContext(); // RName Node1 Node2 something var something = parameters[2]; string expression = null; if (something is AssignmentParameter asp) { expression = asp.Value; } else { expression = something.Image; } if (evalContext.HaveSpiceProperties(expression) || evalContext.HaveFunctions(expression)) { BehavioralResistor behavioralResistor = new BehavioralResistor(name); context.CreateNodes(behavioralResistor, parameters.Take(BehavioralResistor.BehavioralResistorPinCount)); behavioralResistor.Parameters.Expression = expression; behavioralResistor.Parameters.ParseAction = (expression) => { var parser = new ExpressionParser(context.Evaluator.GetEvaluationContext(null), false, context.CaseSensitivity); return(parser.Resolve(expression)); }; if (evalContext.HaveFunctions(expression)) { context.SimulationPreparations.ExecuteActionBeforeSetup((simulation) => { behavioralResistor.Parameters.Expression = expression.ToString(); behavioralResistor.Parameters.ParseAction = (expression) => { var parser = new ExpressionParser(context.Evaluator.GetEvaluationContext(simulation), false, context.CaseSensitivity); return(parser.Resolve(expression)); }; }); } return(behavioralResistor); } } Resistor res = new Resistor(name); context.CreateNodes(res, parameters); if (parameters.Count == 3) { // RName Node1 Node2 something var something = parameters[2]; // Check if something is a model name if ((something is WordParameter || something is IdentifierParameter) && context.ModelsRegistry.FindModel(parameters.Get(2).Image) != null) { // RName Node1 Node2 modelName context.Result.Validation.Add( new ValidationEntry( ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"R parameter needs to be specified", parameters.LineInfo)); return(null); } // Check if something can be resistance if (!(something is WordParameter || something is IdentifierParameter || something is ValueParameter || something is ExpressionParameter || (something is AssignmentParameter ap && (ap.Name.ToLower() == "r" || ap.Name.ToLower() == "resistance")))) { context.Result.Validation.Add( new ValidationEntry( ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Third parameter needs to represent resistance of resistor", parameters.LineInfo)); return(null); } // Set resistance if (something is AssignmentParameter asp) { context.SetParameter(res, "resistance", asp, true, false); } else { context.SetParameter(res, "resistance", something, true, false); } } else { var resistorParameters = new List <Parameter>(parameters.Skip(Resistor.ResistorPinCount).ToArray()); // RName Node1 Node2 something param1 ... if (resistorParameters.Count == 0) { context.Result.Validation.Add( new ValidationEntry( ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Resistor doesn't have at least 3 parameters", parameters.LineInfo)); return(null); } var something = resistorParameters[0]; // Check if something is a model name bool hasModelSyntax = (something is WordParameter || something is IdentifierParameter) && context.ModelsRegistry.FindModel(something.Image) != null; bool hasTcParameter = parameters.Any( p => p is AssignmentParameter ap && ap.Name.Equals( "tc", false ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase)); AssignmentParameter tcParameter = null; if (hasTcParameter) { tcParameter = (AssignmentParameter)parameters.Single( p => p is AssignmentParameter ap && ap.Name.Equals( "tc", false ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase)); resistorParameters.Remove(tcParameter); } if (hasModelSyntax) { var modelNameParameter = resistorParameters[0]; // Ignore tc parameter on resistor ... context.SimulationPreparations.ExecuteActionBeforeSetup((simulation) => { context.ModelsRegistry.SetModel( res, simulation, modelNameParameter, $"Could not find model {modelNameParameter} for resistor {name}", (Context.Models.Model model) => res.Model = model.Name, context.Result); }); resistorParameters.RemoveAt(0); if (resistorParameters.Count > 0 && (resistorParameters[0] is WordParameter || resistorParameters[0] is IdentifierParameter || resistorParameters[0] is ValueParameter || resistorParameters[0] is ExpressionParameter)) { context.SetParameter(res, "resistance", resistorParameters[0].Image, true, false); resistorParameters.RemoveAt(0); } } else { if (hasTcParameter) { var model = new ResistorModel(res.Name + "_default_model"); if (tcParameter.Values.Count == 2) { context.SetParameter(model, "tc1", tcParameter.Values[0]); context.SetParameter(model, "tc2", tcParameter.Values[1]); } else { context.SetParameter(model, "tc1", tcParameter.Value); } context.ModelsRegistry.RegisterModelInstance(new Context.Models.Model(model.Name, model, model.Parameters)); res.Model = model.Name; context.Result.AddEntity(model); } // Check if something can be resistance var resistanceParameter = resistorParameters[0]; if (!(resistanceParameter is WordParameter || resistanceParameter is IdentifierParameter || resistanceParameter is ValueParameter || resistanceParameter is ExpressionParameter || (resistanceParameter is AssignmentParameter ap && (ap.Name.ToLower() == "r" || ap.Name.ToLower() == "resistance")))) { context.Result.Validation.Add( new ValidationEntry( ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Invalid value for resistance", parameters.LineInfo)); return(null); } if (resistanceParameter is AssignmentParameter asp) { context.SetParameter(res, "resistance", asp.Value, true, false); } else { context.SetParameter(res, "resistance", resistanceParameter.Image, true, false); } resistorParameters.RemoveAt(0); } foreach (var parameter in resistorParameters) { if (parameter is AssignmentParameter ap) { try { context.SetParameter(res, ap.Name, ap.Value); } catch (Exception e) { context.Result.Validation.Add( new ValidationEntry( ValidationEntrySource.Reader, ValidationEntryLevel.Error, $"Can't set parameter for resistor: '{parameter.Image}'", parameters.LineInfo, exception: e)); return(null); } } else { context.Result.Validation.Add( new ValidationEntry( ValidationEntrySource.Reader, ValidationEntryLevel.Error, $"Invalid parameter for resistor: '{parameter.Image}'", parameters.LineInfo)); return(null); } } } return(res); }
public SpiceSharp.Components.Component Generate(string componentIdentifier, string originalName, string type, ParameterCollection parameters, ICircuitContext context) { if (parameters.Count < 3) { throw new System.Exception("Model expected"); } Diode diode = new Diode(componentIdentifier); context.CreateNodes(diode, parameters); context.SimulationPreparations.ExecuteActionBeforeSetup((simulation) => { context.ModelsRegistry.SetModel( diode, simulation, parameters.Get(2), $"Could not find model {parameters.Get(2)} for diode {originalName}", (DiodeModel model) => diode.Model = model.Name, context.Result); }); // Read the rest of the parameters for (int i = 3; i < parameters.Count; i++) { if (parameters[i] is WordParameter w) { if (w.Image.ToLower() == "on") { diode.SetParameter("off", false); } else if (w.Image.ToLower() == "off") { diode.SetParameter("off", true); } else { throw new System.Exception("Expected on/off for diode"); } } if (parameters[i] is AssignmentParameter asg) { if (asg.Name.ToLower() == "ic") { context.SetParameter(diode, "ic", asg.Value); } } if (parameters[i] is ValueParameter || parameters[i] is ExpressionParameter) { // TODO: Fix this please it's broken ... var bp = diode.ParameterSets.Get <SpiceSharp.Components.DiodeBehaviors.BaseParameters>(); if (!bp.Area.Given) { bp.Area.Value = context.Evaluator.EvaluateDouble(parameters.Get(i)); } else { if (!bp.Temperature.Given) { bp.Temperature.Value = context.Evaluator.EvaluateDouble(parameters.Get(i)); } } } } return(diode); }
/// <summary> /// Generates a new capacitor. /// </summary> /// <param name="name">Name of capacitor to generate.</param> /// <param name="parameters">Parameters and pins for capacitor.</param> /// <param name="context">Reading context.</param> /// <returns> /// A new instance of capacitor. /// </returns> protected SpiceSharp.Components.IComponent GenerateCap(string name, ParameterCollection parameters, ICircuitContext context) { if (parameters.Count == 3) { // CXXXXXXX N1 N2 VALUE var evalContext = context.Evaluator.GetEvaluationContext(); var something = parameters[2]; string expression = null; if (something is AssignmentParameter asp) { expression = $"({asp.Value}) * x"; } else { expression = $"({something.Image}) * x"; } if (evalContext.HaveSpiceProperties(expression) || evalContext.HaveFunctions(expression)) { BehavioralCapacitor behavioralCapacitor = new BehavioralCapacitor(name); context.CreateNodes(behavioralCapacitor, parameters.Take(BehavioralCapacitor.BehavioralCapacitorPinCount)); behavioralCapacitor.Parameters.Expression = expression; behavioralCapacitor.Parameters.ParseAction = (expression) => { var parser = new ExpressionParser(context.Evaluator.GetEvaluationContext(null), false, context.CaseSensitivity); return(parser.Resolve(expression)); }; evalContext.Parameters.Add("x", new SpiceSharpParser.Common.Evaluation.Expressions.ConstantExpression(1)); if (evalContext.HaveFunctions(expression)) { context.SimulationPreparations.ExecuteActionBeforeSetup((simulation) => { behavioralCapacitor.Parameters.Expression = expression.ToString(); behavioralCapacitor.Parameters.ParseAction = (expression) => { var parser = new ExpressionParser(context.Evaluator.GetEvaluationContext(simulation), false, context.CaseSensitivity); return(parser.Resolve(expression)); }; }); } evalContext.Parameters.Remove("x"); return(behavioralCapacitor); } } var capacitor = new Capacitor(name); context.CreateNodes(capacitor, parameters); // Get TC Parameter Parameter tcParameter = parameters.FirstOrDefault( p => p is AssignmentParameter ap && ap.Name.Equals( "tc", false ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase)); if (tcParameter != null) { parameters.Remove(tcParameter); } bool modelBased = false; if (parameters.Count == 3) { // CXXXXXXX N1 N2 VALUE if (parameters[2] is ValueParameter) { context.SetParameter(capacitor, "capacitance", parameters.Get(2), true, false); } else { context.Result.Validation.Add( new ValidationEntry( ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Wrong parameter value for capacitance", parameters.LineInfo)); return(null); } } else { // CXXXXXXX N1 N2 <VALUE> <MNAME> <L=LENGTH> <W=WIDTH> <IC=VAL> // Examples: // CMOD 3 7 CMODEL L = 10u W = 1u // CMOD 3 7 CMODEL L = 10u W = 1u IC=1 // CMOD 3 7 1.3 IC=1 if (parameters[2] is ValueParameter) { context.SetParameter(capacitor, "capacitance", parameters.Get(2), true, false); } else { context.SimulationPreparations.ExecuteActionBeforeSetup((simulation) => { context.ModelsRegistry.SetModel( capacitor, simulation, parameters.Get(2), $"Could not find model {parameters.Get(2)} for capacitor {name}", (Context.Models.Model model) => capacitor.Model = model.Name, context.Result); }); modelBased = true; } SetParameters(context, capacitor, parameters.Skip(3), true); if (modelBased) { var bp = capacitor.GetParameterSet <ModelParameters>(); /*if (bp == null || !bp.Length.Given) * { * context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, * ValidationEntryLevel.Warning, * $"L needs to be specified", parameters.LineInfo)); * return null; * }*/ } } if (tcParameter != null) { var tcParameterAssignment = tcParameter as AssignmentParameter; if (tcParameterAssignment == null) { context.Result.Validation.Add( new ValidationEntry( ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"TC needs to be assignment parameter", parameters.LineInfo)); return(null); } if (modelBased) { var model = context.ModelsRegistry.FindModelEntity(parameters.Get(2).Image); if (tcParameterAssignment.Values.Count == 2) { context.SetParameter(model, "tc1", tcParameterAssignment.Values[0], true, false); context.SetParameter(model, "tc2", tcParameterAssignment.Values[1], true, false); } else { context.SetParameter(model, "tc1", tcParameterAssignment.Value); } context.Result.AddEntity(model); capacitor.Model = model.Name; } else { var model = new CapacitorModel(capacitor.Name + "_default_model"); if (tcParameterAssignment.Values.Count == 2) { context.SetParameter(model, "tc1", tcParameterAssignment.Values[0], true, false); context.SetParameter(model, "tc2", tcParameterAssignment.Values[1], true, false); } else { context.SetParameter(model, "tc1", tcParameterAssignment.Value); } context.ModelsRegistry.RegisterModelInstance(new Context.Models.Model(model.Name, model, model.Parameters)); context.Result.AddEntity(model); capacitor.Model = model.Name; } } return(capacitor); }
public SpiceSharp.Components.Component Generate(string componentIdentifier, string originalName, string type, ParameterCollection parameters, ICircuitContext context) { BipolarJunctionTransistor bjt = new BipolarJunctionTransistor(componentIdentifier); // If the component is of the format QXXX NC NB NE MNAME off we will insert NE again before the model name if (parameters.Count == 5 && parameters[4] is WordParameter w && w.Image == "off") { parameters.Insert(3, parameters[2]); } // If the component is of the format QXXX NC NB NE MNAME we will insert NE again before the model name if (parameters.Count == 4) { parameters.Insert(3, parameters[2]); } context.CreateNodes(bjt, parameters); if (parameters.Count < 5) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, "Wrong parameters count for BJT", parameters.LineInfo)); return(null); } context.SimulationPreparations.ExecuteActionBeforeSetup((simulation) => { context.ModelsRegistry.SetModel( bjt, simulation, parameters.Get(4), $"Could not find model {parameters.Get(4)} for BJT {originalName}", (BipolarJunctionTransistorModel model) => bjt.Model = model.Name, context.Result); }); for (int i = 5; i < parameters.Count; i++) { var parameter = parameters[i]; if (parameter is SingleParameter s) { if (s is WordParameter) { switch (s.Image.ToLower()) { case "on": bjt.SetParameter("off", false); break; case "off": bjt.SetParameter("on", false); break; default: throw new System.Exception(); } } else { // TODO: Fix this please it's broken ... BaseParameters bp = bjt.ParameterSets.Get <BaseParameters>(); if (!bp.Area.Given) { bp.Area.Value = context.Evaluator.EvaluateDouble(s.Image); } if (!bp.Temperature.Given) { bp.Temperature.Value = context.Evaluator.EvaluateDouble(s.Image); } } } if (parameter is AssignmentParameter asg) { if (asg.Name.ToLower() == "ic") { context.SetParameter(bjt, "ic", asg.Value); } } } return(bjt); }
/// <summary> /// Generates a current switch. /// </summary> /// <param name="name">Name of current switch.</param> /// <param name="parameters">Parameters of current switch.</param> /// <param name="context">Reading context.</param> /// <returns> /// A new instance of current switch. /// </returns> protected SpiceSharp.Components.Component GenerateCurrentSwitch(string name, ParameterCollection parameters, ICircuitContext context) { if (parameters.Count < 4) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, "Wrong parameter count for current switch", parameters.LineInfo)); return(null); } string modelName = parameters.Get(3).Image; if (context.ModelsRegistry.FindModel <Model>(modelName) is ISwitchModel s) { Resistor resistor = new Resistor(name); Model resistorModel = s; context.CreateNodes(resistor, parameters.Take(2)); context.SimulationPreparations.ExecuteTemperatureBehaviorBeforeLoad(resistor); context.SimulationPreparations.ExecuteActionBeforeSetup( (simulation) => { if (context.ModelsRegistry is StochasticModelsRegistry stochasticModelsRegistry) { resistorModel = stochasticModelsRegistry.ProvideStochasticModel(name, simulation, s); if (!context.Result.FindObject(resistorModel.Name, out _)) { stochasticModelsRegistry.RegisterModelInstance(resistorModel); context.Result.Circuit.Add(resistorModel); } } double rOff = resistorModel.ParameterSets.GetParameter <double>("roff"); string resExpression = $"pos(table(i({parameters.Get(2)}), @{resistorModel.Name}[ioff], @{resistorModel.Name}[roff] , @{resistorModel.Name}[ion], @{resistorModel.Name}[ron]), {rOff.ToString(CultureInfo.InvariantCulture)})"; context.SetParameter(resistor, "resistance", resExpression, beforeTemperature: true, onload: true); }); return(resistor); } else { CurrentSwitch csw = new CurrentSwitch(name); context.CreateNodes(csw, parameters); // Get the controlling voltage source if (parameters[2] is WordParameter || parameters[2] is IdentifierParameter) { csw.ControllingName = context.NameGenerator.GenerateObjectName(parameters.Get(2).Image); } else { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, "Voltage source name expected", parameters.LineInfo)); return(null); } // Get the model context.SimulationPreparations.ExecuteActionBeforeSetup((simulation) => { context.ModelsRegistry.SetModel( csw, simulation, parameters.Get(3), $"Could not find model {parameters.Get(3)} for current switch {name}", (CurrentSwitchModel model) => csw.Model = model.Name, context.Result); }); // Optional on or off if (parameters.Count > 4) { switch (parameters.Get(4).Image.ToLower()) { case "on": csw.ParameterSets.SetParameter("on"); break; case "off": csw.ParameterSets.SetParameter("off"); break; default: context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, "ON or OFF expected", parameters.LineInfo)); return(csw); } } return(csw); } }
/// <summary> /// Generate resistor. /// </summary> /// <param name="name">Name of resistor to generate.</param> /// <param name="parameters">Parameters and pins for resistor.</param> /// <param name="context">Reading context.</param> /// <returns> /// A new instance of resistor. /// </returns> protected SpiceSharp.Components.Component GenerateRes(string name, ParameterCollection parameters, ICircuitContext context) { Resistor res = new Resistor(name); var dynamicParameter = parameters.FirstOrDefault(p => p.Image == "dynamic"); if (dynamicParameter != null) { parameters.Remove(dynamicParameter); } bool isDynamic = dynamicParameter != null || context.Result?.SimulationConfiguration?.DynamicResistors == true; if (isDynamic) { context.SimulationPreparations.ExecuteTemperatureBehaviorBeforeLoad(res); } context.CreateNodes(res, parameters); if (parameters.Count == 3) { // RName Node1 Node2 something var something = parameters[2]; // Check if something is a model name if ((something is WordParameter || something is IdentifierParameter) && context.ModelsRegistry.FindModel <ResistorModel>(parameters.Get(2).Image) != null) { // RName Node1 Node2 modelName context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"R parameter needs to be specified", parameters.LineInfo)); return(null); } // Check if something can be resistance if (!(something is WordParameter || something is IdentifierParameter || something is ValueParameter || something is ExpressionParameter || (something is AssignmentParameter ap && (ap.Name.ToLower() == "r" || ap.Name.ToLower() == "resistance")))) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Third parameter needs to represent resistance of resistor", parameters.LineInfo)); return(null); } // Set resistance if (something is AssignmentParameter asp) { context.SetParameter(res, "resistance", asp, true, isDynamic); } else { context.SetParameter(res, "resistance", something, true, isDynamic); } } else { var resistorParameters = new List <Parameter>(parameters.Skip(Resistor.ResistorPinCount).ToArray()); // RName Node1 Node2 something param1 ... if (resistorParameters.Count == 0) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Resistor doesn't have at least 3 parameters", parameters.LineInfo)); return(null); } var something = resistorParameters[0]; // Check if something is a model name bool hasModelSyntax = (something is WordParameter || something is IdentifierParameter) && context.ModelsRegistry.FindModel <ResistorModel>(something.Image) != null; bool hasTcParameter = parameters.Any( p => p is AssignmentParameter ap && ap.Name.Equals( "tc", context.CaseSensitivity.IsEntityParameterNameCaseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase)); AssignmentParameter tcParameter = null; if (hasTcParameter) { tcParameter = (AssignmentParameter)parameters.Single( p => p is AssignmentParameter ap && ap.Name.Equals( "tc", context.CaseSensitivity.IsEntityParameterNameCaseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase)); resistorParameters.Remove(tcParameter); } if (hasModelSyntax) { var modelNameParameter = resistorParameters[0]; // Ignore tc parameter on resistor ... context.SimulationPreparations.ExecuteActionBeforeSetup((simulation) => { context.ModelsRegistry.SetModel( res, simulation, modelNameParameter, $"Could not find model {modelNameParameter} for resistor {name}", (ResistorModel model) => res.Model = model.Name, context.Result); }); resistorParameters.RemoveAt(0); if (resistorParameters.Count > 0 && (resistorParameters[0] is WordParameter || resistorParameters[0] is IdentifierParameter || resistorParameters[0] is ValueParameter || resistorParameters[0] is ExpressionParameter)) { context.SetParameter(res, "resistance", resistorParameters[0].Image, true); resistorParameters.RemoveAt(0); } } else { if (hasTcParameter) { var model = new ResistorModel(res.Name + "_default_model"); if (tcParameter.Values.Count == 2) { context.SetParameter(model, "tc1", tcParameter.Values[0]); context.SetParameter(model, "tc2", tcParameter.Values[1]); } else { context.SetParameter(model, "tc1", tcParameter.Value); } context.ModelsRegistry.RegisterModelInstance(model); res.Model = model.Name; context.Result.AddEntity(model); } // Check if something can be resistance var resistanceParameter = resistorParameters[0]; if (!(resistanceParameter is WordParameter || resistanceParameter is IdentifierParameter || resistanceParameter is ValueParameter || resistanceParameter is ExpressionParameter || (resistanceParameter is AssignmentParameter ap && !(ap.Name.ToLower() == "r" || ap.Name.ToLower() == "resistance")))) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Invalid value for resistance", parameters.LineInfo)); return(null); } if (resistanceParameter is AssignmentParameter asp) { context.SetParameter(res, "resistance", asp.Value, true, isDynamic); } else { context.SetParameter(res, "resistance", resistanceParameter.Image, true, isDynamic); } resistorParameters.RemoveAt(0); } foreach (var parameter in resistorParameters) { if (parameter is AssignmentParameter ap) { try { context.SetParameter(res, ap.Name, ap.Value); } catch (Exception e) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Can't set parameter for resistor: '{parameter.Image}'", parameters.LineInfo)); return(null); } } else { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, $"Invalid parameter for resistor: '{parameter.Image}'", parameters.LineInfo)); return(null); } } } return(res); }
/// <summary> /// Generates a voltage switch. /// </summary> /// <param name="name">Name of voltage switch to generate.</param> /// <param name="parameters">Parameters for voltage switch.</param> /// <param name="context">Reading context.</param> /// <returns> /// A new voltage switch. /// </returns> protected SpiceSharp.Components.Component GenerateVoltageSwitch(string name, ParameterCollection parameters, ICircuitContext context) { if (parameters.Count < 5) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, "Wrong parameter count for voltage switch", parameters.LineInfo)); return(null); } string modelName = parameters.Get(4).Image; if (context.ModelsRegistry.FindModel <Model>(modelName) is VSwitchModel vmodel) { Resistor resistor = new Resistor(name); Model resistorModel = vmodel; context.CreateNodes(resistor, parameters.Take(2)); context.SimulationPreparations.ExecuteTemperatureBehaviorBeforeLoad(resistor); context.SimulationPreparations.ExecuteActionBeforeSetup( (simulation) => { if (context.ModelsRegistry is StochasticModelsRegistry stochasticModelsRegistry) { resistorModel = stochasticModelsRegistry.ProvideStochasticModel(name, simulation, vmodel); if (!context.Result.FindObject(resistorModel.Name, out _)) { stochasticModelsRegistry.RegisterModelInstance(resistorModel); context.Result.Circuit.Add(resistorModel); } } string resExpression = $"table(v({parameters.Get(2)}, {parameters.Get(3)}), @{resistorModel.Name}[voff], @{resistorModel.Name}[roff] , @{resistorModel.Name}[von], @{resistorModel.Name}[ron])"; context.SetParameter(resistor, "resistance", resExpression, beforeTemperature: true, onload: true); }); return(resistor); } else { VoltageSwitch vsw = new VoltageSwitch(name); context.CreateNodes(vsw, parameters); context.SimulationPreparations.ExecuteActionBeforeSetup((simulation) => { context.ModelsRegistry.SetModel( vsw, simulation, parameters.Get(4), $"Could not find model {parameters.Get(4)} for voltage switch {name}", (VoltageSwitchModel model) => { vsw.Model = model.Name; }, context.Result); }); // Optional ON or OFF if (parameters.Count == 6) { switch (parameters.Get(5).Image.ToLower()) { case "on": vsw.ParameterSets.SetParameter("on"); break; case "off": vsw.ParameterSets.SetParameter("off"); break; default: context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, "ON or OFF expected", parameters.LineInfo)); return(vsw); } } else if (parameters.Count > 6) { context.Result.Validation.Add(new ValidationEntry(ValidationEntrySource.Reader, ValidationEntryLevel.Warning, "Too many parameters for voltage switch", parameters.LineInfo)); return(vsw); } return(vsw); } }