public void When_IsTemperatureDependent_Expect_Reference() { /* * A test for a lowpass RC circuit (DC voltage, resistor, capacitor) * The initial voltage on capacitor is 0V. The result should be an exponential converging to dcVoltage. * TC1 and TC2 of capacitor is 0. * Temperature is 30 degrees. */ double dcVoltage = 10; var resistorResistance = 10e3; // 10000; double factor = (1.0 + 3.0 * 1.1 + 3.0 * 3.0 * 2.1); var capacitance = 1e-6; var capacitanceAfterTemperature = capacitance * factor; var tau = resistorResistance * capacitanceAfterTemperature; var capacitor = new Capacitor("C1", "OUT", "0", capacitance); var model = new CapacitorModel("model C1"); model.Parameters.TemperatureCoefficient1 = 1.1; model.Parameters.TemperatureCoefficient2 = 2.1; capacitor.Model = model.Name; // Build circuit var ckt = new Circuit( model, capacitor, new Resistor("R1", "IN", "OUT", resistorResistance), new VoltageSource("V1", "IN", "0", dcVoltage)); // Create simulation, exports and references var tran = new Transient("tran", 1e-8, 10e-6); tran.TimeParameters.InitialConditions["OUT"] = 0.0; tran.BeforeTemperature += (sender, args) => { var state = tran.GetState <ITemperatureSimulationState>(); ((TemperatureSimulationState)state).Temperature = Constants.CelsiusKelvin + 30.0; }; IExport <double>[] exports = { new RealPropertyExport(tran, "C1", "v") }; Func <double, double>[] references = { t => dcVoltage * (1.0 - Math.Exp(-t / tau)) }; // Run AnalyzeTransient(tran, ckt, exports, references); DestroyExports(exports); }
public override Context.Models.Model Generate(string id, string type, ParameterCollection parameters, ICircuitContext context) { switch (type.ToLower()) { case "res": case "r": var model = new ResistorModel(id); SetParameters(context, model, parameters); return(new Context.Models.Model(id, model, model.Parameters)); case "c": var model2 = new CapacitorModel(id); SetParameters(context, model2, parameters); return(new Context.Models.Model(id, model2, model2.Parameters)); } return(null); }
public void When_CapacitorIsTemperatureInvariant_Expect_Reference() { /* * A test for a lowpass RC circuit (DC voltage, resistor, capacitor) * The initial voltage on capacitor is 0V. The result should be an exponential converging to dcVoltage. * TC1 and TC2 of capacitor is 0. * Temperature is 30 degrees. */ double dcVoltage = 10; var resistorResistance = 10e3; // 10000; var capacitance = 1e-6; // 0.000001; var tau = resistorResistance * capacitance; var capacitor = new Capacitor("C1", "OUT", "0", capacitance); var model = new CapacitorModel("model C1"); model.ParameterSets.Get <ModelBaseParameters>().TemperatureCoefficient1.Value = 0.0; model.ParameterSets.Get <ModelBaseParameters>().TemperatureCoefficient2.Value = 0.0; capacitor.Model = model.Name; // Build circuit var ckt = new Circuit( model, capacitor, new Resistor("R1", "IN", "OUT", resistorResistance), new VoltageSource("V1", "IN", "0", dcVoltage)); // Create simulation, exports and references var tran = new Transient("tran", 1e-8, 10e-6); tran.Configurations.Get <TimeConfiguration>().InitialConditions["OUT"] = 0.0; tran.BeforeTemperature += (sender, args) => { ((BaseSimulationState)args.State).Temperature = Constants.CelsiusKelvin + 30.0; }; Export <double>[] exports = { new RealPropertyExport(tran, "C1", "v") }; Func <double, double>[] references = { t => dcVoltage * (1.0 - Math.Exp(-t / tau)) }; // Run AnalyzeTransient(tran, ckt, exports, references); DestroyExports(exports); }
public override SpiceSharp.Components.Model Generate(string id, string type, ParameterCollection parameters, ICircuitContext context) { SpiceSharp.Components.Model model = null; switch (type.ToLower()) { case "res": case "r": model = new ResistorModel(id); break; case "c": model = new CapacitorModel(id); break; } if (model != null) { SetParameters(context, model, parameters); } return(model); }
/// <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); }
/// <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); }