Circuit Element Example |
Below, an example implementation of a RelaxISPlugin_CircuitElement2 is shown.
The function of the plugin is chosen for illustrative purposes.
Please note, that the example does not apply to the legacy RelaxISPlugin_CircuitElement type. This class is now obsolete and just kept for backwards compatibility.
Reference to the RelaxIS_SDK.dll
.NET Framework 4.7.2 target (class library)
Recommended: Development environment with compiler e.g. RelaxIS SDK Code Editor, Microsoft Visual Studio
This examples illustrates the implementation of a Circuit Element plugin.
The plugin reimplements the Constant Phase Element (CPE) as an example.
Caution |
---|
The legacy RelaxISPlugin_CircuitElement and the RelaxISPlugin_CircuitElement2 use different definitions for the use of the parameter array in the Impedance function! For legacy RelaxISPlugin_CircuitElement plugins, the parameters array only contains parameters for this particular element, so the first parameter is found at parameters[0]. For newer RelaxISPlugin_CircuitElement2 plugin, however is called with a parameters array that contains parameter values for the full model. The additional pStartIndex parameter defines the index of the first parameter for this element in the array. So the first parameter is found at parameters[pStartIndex + 0]. |
// <copyright file="MyCircuitElement.cs" company="rhd instruments GmbH and Co. KG"> // Copyright (c) rhd instruments GmbH and Co. KG. All rights reserved. // Licensed under the MIT No Attribution (MIT-0) license. See section 'License' in the 'SDK Examples / Tutorials' topic for full license information. // </copyright> namespace RelaxIS_SDK_Examples.Plugins { /*** * CircuitElement plugins are used to implement custom model functions to RelaxIS. * These can be used as a full standalone model or as part of a larger equivalent circuit model. */ /*** * CAUTION! * The plugin is identified in a fit model by its Abbreviation property. * A RelaxIS Project (.eis3) file contains fits in the form of the model string and parameters. * That means, if you don't have all the correct plugins, you won't be able to open an .eis3 file that uses it. * This also applies if you have a plugin with the correct abbreviation but a different number of parameters. * Furthermore, if you have a plugin with the same Abbreviation and parameter number but a different mathematical expression * the displayed fit curves and new fits won't match the existing information! * It is also important to only have unique abbreviations, so make sure to not reuse an existing abbreviation. */ using System; using System.Collections.Generic; using System.Linq; using RelaxIS_SDK.Common; using RelaxIS_SDK.libMath; using RelaxIS_SDK.Plugins; /// <summary> /// Defines an example <see cref="RelaxISPlugin_CircuitElement2"/> class. /// </summary> public class MyCircuitElement : RelaxISPlugin_CircuitElement2 { /*** * First, implement the default plugin properties Name and Description that describe the plugin. * This is mainly used for display purposes. */ /// <inheritdoc/> public override string Name { get { return "MyCircuitElement"; } } /// <inheritdoc/> public override string Description { get { return "An example CircuitElement, that recreates the CPE calculation."; } } /*** * The Formula property is used for display purposes only. It is not involved in model calculations. */ /// <inheritdoc/> public override string Formula { get { return "Z = 1/((i * w) ^ a * Q)"; } } /*** * The Abbreviation property is very important. * It identifies this model in a RelaxIS model string. * It must start with exactly one uppercase letter, followed only by lowercase letters and numbers. */ /// <inheritdoc/> public override string Abbreviation { get { return "Mycpe"; } } /*** * This property defines which parameters the circuit element uses. * This defines the default parameter values, limits and fixed-states. * The order of this list determines the order in which the parameter values * are passed into the CalculateImpedance function by RelaxIS. */ /// <inheritdoc/> public override IReadOnlyCollection<Fitparameter> StandardParameters { get { return new List<Fitparameter>() { new Fitparameter("Q", false, 1e-6, 0, 1e-15, 1e15), new Fitparameter("alpha", false, 0.95, 0, 0.15, 1), }; } } /*** * This function calculates an impedance value based on the given frequency and parameters. * Always return an impedance value, and not a value in a different transfer function. * The parameters array contains parameter values for the full model. We use the pStartIndex parameter * to find the first parameter belonging to this model. * The order of the parameters is then the same as they were defined in the StandardParameters property. * Please note, that this is a performance critical function. It will be called very often during a fit, * and therefore directly influences the fit performance. */ /// <inheritdoc/> public override Complex CalculateImpedance(double frequency, double[] parameters, int pStartIndex) { // Get the parameter values from the parameter array. var q = parameters[pStartIndex + 0]; var a = parameters[pStartIndex + 1]; // Calculate i * Omega var iw = new Complex(0, 2.0 * Math.PI * frequency); var iwa = Complex.Pow(iw, a); return 1.0 / (iwa * q); } /*** * Overriding this function is optional. It is used mainly for the Auto Fit function in RelaxIS. * Here, before the autofit is started, this function is called to allow the plugin to analyze * the input spectrum and determine suitable parameter limits for it. * This new limit will be used in case the user has not defined custom limits for the particular parameter. * Implementing tight limits here will drastically improve the success rate of the Auto Fit. */ /// <inheritdoc/> public override IReadOnlyCollection<Limits> GetTightLimits(ImpedanceSpectrum Spectrum) { // Calculate the complex capacitances from the data var caps = Spectrum.Data.Select(p => 1.0 / (new Complex(0, 2.0 * Math.PI * p.Impedance.Frequency) * new Complex(p.Impedance.Real, p.Impedance.Imaginary))); // Take the minimum and maximum real capacitances and scale them by a factor for the new limits var cMin = caps.Min(c => c.Real) / 10000; var cMax = caps.Max(c => c.Real) * 10000; // If the spectrum has positive imaginary parts, use -1 as the lower-limit, otherwise 0.4 var hasPositiveImag = Spectrum.Data.Where(p => p.Impedance.Imaginary > 0).Any(); var aMin = hasPositiveImag ? -1 : 0.4; return new List<Limits>() { new Limits(cMin / 10000, cMax * 10000), new Limits(aMin, 1), }; } } }