From f1df831716ddf4a25f7e82078e537d48bf4ce8d7 Mon Sep 17 00:00:00 2001 From: Carl Philipp Klemm <philipp@uvos.xyz> Date: Tue, 24 May 2022 10:18:32 +0200 Subject: [PATCH] add finite transmitison line aproximation improve handling of model copys deduplicate componant <-> char asssingment by implementing static and virtual members fix bug in parameter parser preventing the use of models with no parameters dropped support for captalized model chars in model string add const function alternative for executeParamByIndex to allow jet another threading model to be used add improved error checkig to parameter range processing add the ability to warn the user when a range is applied to a unexpected componant via range tagging omega ranges are now log by default --- CMakeLists.txt | 1 + cap.cpp | 5 + componant.cpp | 41 ++----- constantphase.cpp | 5 + eisgenerator/cap.h | 2 + eisgenerator/componant.h | 2 +- eisgenerator/constantphase.h | 3 + eisgenerator/eistype.h | 3 +- eisgenerator/finitetr.h | 30 +++++ eisgenerator/inductor.h | 2 + eisgenerator/log.h | 4 +- eisgenerator/model.h | 17 +-- eisgenerator/paralellseriel.h | 4 + eisgenerator/resistor.h | 2 + eisgenerator/warburg.h | 2 + finitetr.cpp | 137 ++++++++++++++++++++++ inductor.cpp | 5 + log.cpp | 5 +- main.cpp | 2 +- model.cpp | 215 +++++++++++++++++++++++++--------- options.h | 6 +- paralellseriel.cpp | 10 ++ resistor.cpp | 5 + test.cpp | 2 +- warburg.cpp | 7 +- 25 files changed, 415 insertions(+), 102 deletions(-) create mode 100644 eisgenerator/finitetr.h create mode 100644 finitetr.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f33bfe..a390c51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ set(SRC_FILES log.cpp normalize.cpp basicmath.cpp + finitetr.cpp ) set(API_HEADERS_CPP_DIR eisgenerator/) diff --git a/cap.cpp b/cap.cpp index 61e9041..19933dd 100644 --- a/cap.cpp +++ b/cap.cpp @@ -56,6 +56,11 @@ void Cap::setParam(const std::vector<fvalue>& param) _C = param[0]; } +char Cap::getComponantChar() const +{ + return Cap::staticGetComponantChar(); +} + size_t Cap::paramCount() { return 1; diff --git a/componant.cpp b/componant.cpp index 7ea0e0b..f0e29eb 100644 --- a/componant.cpp +++ b/componant.cpp @@ -7,51 +7,34 @@ #include "warburg.h" #include "log.h" #include "inductor.h" +#include "finitetr.h" using namespace eis; Componant* Componant::copy(Componant* componant) { - switch(getComponantChar(componant)) + switch(componant->getComponantChar()) { - case 'r': + case Resistor::staticGetComponantChar(): return new Resistor(*dynamic_cast<Resistor*>(componant)); - case 'c': + case Cap::staticGetComponantChar(): return new Cap(*dynamic_cast<Cap*>(componant)); - case 'i': + case Inductor::staticGetComponantChar(): return new Inductor(*dynamic_cast<Inductor*>(componant)); - case 'p': + case Cpe::staticGetComponantChar(): return new Cpe(*dynamic_cast<Cpe*>(componant)); - case 'w': + case Warburg::staticGetComponantChar(): return new Warburg(*dynamic_cast<Warburg*>(componant)); - case 'l': + case FiniteTransmitionline::staticGetComponantChar(): + return new FiniteTransmitionline(*dynamic_cast<FiniteTransmitionline*>(componant)); + case Parallel::staticGetComponantChar(): return new Parallel(*dynamic_cast<Parallel*>(componant)); - case 's': + case Serial::staticGetComponantChar(): return new Serial(*dynamic_cast<Serial*>(componant)); default: - Log(Log::ERROR)<<"unimplmented type copy for "<<getComponantChar(componant)<<'\n'; + Log(Log::ERROR)<<"unimplmented type copy for "<<componant->getComponantChar(); assert(0); break; } return nullptr; } - -char Componant::getComponantChar(Componant* componant) -{ - if(dynamic_cast<Resistor*>(componant)) - return 'r'; - if(dynamic_cast<Cap*>(componant)) - return 'c'; - if(dynamic_cast<Inductor*>(componant)) - return 'i'; - if(dynamic_cast<Cpe*>(componant)) - return 'p'; - if(dynamic_cast<Warburg*>(componant)) - return 'w'; - if(dynamic_cast<Parallel*>(componant)) - return 'l'; - if(dynamic_cast<Serial*>(componant)) - return 's'; - - return 'x'; -} diff --git a/constantphase.cpp b/constantphase.cpp index 6022ba8..834a884 100644 --- a/constantphase.cpp +++ b/constantphase.cpp @@ -65,3 +65,8 @@ size_t Cpe::paramCount() { return 2; } + +char Cpe::getComponantChar() const +{ + return Cpe::staticGetComponantChar(); +} diff --git a/eisgenerator/cap.h b/eisgenerator/cap.h index d394f83..e0e66c4 100644 --- a/eisgenerator/cap.h +++ b/eisgenerator/cap.h @@ -18,6 +18,8 @@ public: virtual std::vector<fvalue> getParam() override; virtual void setParam(const std::vector<fvalue>& param) override; virtual size_t paramCount() override; + virtual char getComponantChar() const override; + static constexpr char staticGetComponantChar(){return 'c';} virtual ~Cap() = default; }; diff --git a/eisgenerator/componant.h b/eisgenerator/componant.h index 141049e..eb5ca6d 100644 --- a/eisgenerator/componant.h +++ b/eisgenerator/componant.h @@ -24,9 +24,9 @@ class Componant virtual void setParam(const std::vector<fvalue>& param){}; virtual size_t paramCount(){return 0;} virtual ~Componant() = default; + virtual char getComponantChar() const = 0; static Componant* copy(Componant* componant); - static char getComponantChar(Componant* componant); }; } diff --git a/eisgenerator/constantphase.h b/eisgenerator/constantphase.h index 1158717..0706e26 100644 --- a/eisgenerator/constantphase.h +++ b/eisgenerator/constantphase.h @@ -19,7 +19,10 @@ public: virtual std::vector<fvalue> getParam() override; virtual void setParam(const std::vector<fvalue>& param) override; virtual size_t paramCount() override; + virtual char getComponantChar() const override; + static constexpr char staticGetComponantChar(){return 'p';} virtual ~Cpe() = default; + }; } diff --git a/eisgenerator/eistype.h b/eisgenerator/eistype.h index 43c6e3c..7c0b594 100644 --- a/eisgenerator/eistype.h +++ b/eisgenerator/eistype.h @@ -17,6 +17,7 @@ struct Range fvalue end; size_t count; bool log = false; + char type = 'x'; fvalue stepSize() const { @@ -38,7 +39,7 @@ struct Range { return operator*(static_cast<fvalue>(1.0)/in); } - Range(fvalue startI, fvalue endI, size_t countI, bool logI = false): start(startI), end(endI), count(countI), log(logI){} + Range(fvalue startI, fvalue endI, size_t countI, bool logI = false, char typeI = 'x'): start(startI), end(endI), count(countI), log(logI), type(typeI){} Range() = default; }; diff --git a/eisgenerator/finitetr.h b/eisgenerator/finitetr.h new file mode 100644 index 0000000..fbaf35d --- /dev/null +++ b/eisgenerator/finitetr.h @@ -0,0 +1,30 @@ +#pragma once +#include "componant.h" + +namespace eis +{ + +class FiniteTransmitionline: public Componant +{ + fvalue _C; + fvalue _R; + unsigned int _n; + + Componant* subComponant = nullptr; + + static Componant* createTransmitionLine(fvalue c, fvalue r, unsigned int n); + +public: + FiniteTransmitionline(fvalue c, fvalue r, unsigned int n); + FiniteTransmitionline(std::string paramStr); + FiniteTransmitionline(const FiniteTransmitionline& in); + virtual std::complex<fvalue> execute(fvalue omega) override; + virtual std::vector<fvalue> getParam(); + virtual void setParam(const std::vector<fvalue>& param); + virtual size_t paramCount(); + virtual ~FiniteTransmitionline(); + virtual char getComponantChar() const override; + static constexpr char staticGetComponantChar(){return 't';} +}; + +} diff --git a/eisgenerator/inductor.h b/eisgenerator/inductor.h index 8edba47..a263462 100644 --- a/eisgenerator/inductor.h +++ b/eisgenerator/inductor.h @@ -18,6 +18,8 @@ public: virtual std::vector<fvalue> getParam() override; virtual void setParam(const std::vector<fvalue>& param) override; virtual size_t paramCount() override; + virtual char getComponantChar() const override; + static constexpr char staticGetComponantChar(){return 'l';} virtual ~Inductor() = default; }; diff --git a/eisgenerator/log.h b/eisgenerator/log.h index e07cb23..d4240ca 100644 --- a/eisgenerator/log.h +++ b/eisgenerator/log.h @@ -39,6 +39,7 @@ public: private: bool opened = false; Level msglevel = DEBUG; + bool endline = true; std::string getLabel(Level level); @@ -46,10 +47,9 @@ public: static bool headers; static Level level; - static bool endline; Log() {} - Log(Level type); + Log(Level type, bool endlineI = true); ~Log(); template<class T> Log &operator<<(const T &msg) diff --git a/eisgenerator/model.h b/eisgenerator/model.h index 0a654b3..7f47ccd 100644 --- a/eisgenerator/model.h +++ b/eisgenerator/model.h @@ -1,6 +1,7 @@ #pragma once #include <complex> +#include <cstddef> #include <string> #include <vector> #include <functional> @@ -18,7 +19,8 @@ private: Componant *processBrackets(std::string& str, size_t& bracketCounter); Componant *processBracket(std::string& str); std::string getParamStr(const std::string& str, size_t index); - void addComponantToFlat(Componant* componant); + static void addComponantToFlat(Componant* componant, std::vector<Componant*>* flatComponants); + Componant* flatParameterToFlatComponant(size_t parameterIndex); private: Componant *_model = nullptr; @@ -31,16 +33,17 @@ public: Model(const Model& in); Model& operator=(const Model& in); ~Model(); - DataPoint execute(fvalue omaga); - std::vector<DataPoint> executeSweep(const Range& omega); + DataPoint execute(fvalue omaga, Componant* model); + std::vector<DataPoint> executeSweep(const Range& omega, Componant *model = nullptr); bool executeParamSweep(const std::vector<Range>& componantRanges, const Range& omega, std::function<void(std::vector<DataPoint>&, const std::vector<fvalue>&)> dataCb); std::vector<DataPoint> executeParamByIndex(const std::vector<Range>& componantRanges, const Range& omega, size_t index); - + std::vector<DataPoint> executeParamByIndexC(const std::vector<Range>& componantRanges, const Range& omega, size_t index); std::string getModelStr(); - std::vector<Componant*> getFlatComponants(); - std::vector<fvalue> getFlatParameters(); + std::vector<Componant*> getFlatComponants(Componant *model = nullptr); + std::vector<fvalue> getFlatParameters(Componant *model = nullptr); size_t getFlatParametersCount(); - bool setFlatParameters(const std::vector<fvalue>& parameters); + bool setFlatParameters(const std::vector<fvalue>& parameters, Componant *model = nullptr); + bool checkParameterRanges(const std::vector<eis::Range> ranges, Componant* model = nullptr); static std::vector<fvalue> getSweepParamByIndex(const std::vector<Range>& componantRanges, size_t index); static size_t getRequiredStepsForSweeps(const std::vector<Range>& componantRanges); diff --git a/eisgenerator/paralellseriel.h b/eisgenerator/paralellseriel.h index e764c97..1a63dbf 100644 --- a/eisgenerator/paralellseriel.h +++ b/eisgenerator/paralellseriel.h @@ -16,6 +16,8 @@ public: void operator=(const Parallel& in); ~Parallel(); virtual std::complex<fvalue> execute(fvalue omaga) override; + virtual char getComponantChar() const override; + static constexpr char staticGetComponantChar(){return '|';} }; class Serial: public Componant @@ -28,6 +30,8 @@ public: void operator=(const Serial& in); ~Serial(); virtual std::complex<fvalue> execute(fvalue omaga) override; + virtual char getComponantChar() const override; + static constexpr char staticGetComponantChar(){return 's';} }; } diff --git a/eisgenerator/resistor.h b/eisgenerator/resistor.h index 42bc4d6..f9d412d 100644 --- a/eisgenerator/resistor.h +++ b/eisgenerator/resistor.h @@ -17,6 +17,8 @@ public: virtual std::vector<fvalue> getParam() override; virtual void setParam(const std::vector<fvalue>& param) override; virtual size_t paramCount() override; + virtual char getComponantChar() const override; + static constexpr char staticGetComponantChar(){return 'r';} virtual ~Resistor() = default; }; diff --git a/eisgenerator/warburg.h b/eisgenerator/warburg.h index 0974d99..7fdd8b8 100644 --- a/eisgenerator/warburg.h +++ b/eisgenerator/warburg.h @@ -18,6 +18,8 @@ public: virtual std::vector<fvalue> getParam() override; virtual void setParam(const std::vector<fvalue>& param) override; virtual size_t paramCount() override; + virtual char getComponantChar() const override; + static constexpr char staticGetComponantChar(){return 'w';} virtual ~Warburg() = default; }; diff --git a/finitetr.cpp b/finitetr.cpp new file mode 100644 index 0000000..a69487a --- /dev/null +++ b/finitetr.cpp @@ -0,0 +1,137 @@ +#include "finitetr.h" +#include <cstdlib> +#include <math.h> + +#include "eisgenerator/componant.h" +#include "eisgenerator/paralellseriel.h" +#include "eisgenerator/resistor.h" +#include "paralellseriel.h" +#include "cap.h" +#include "resistor.h" +#include "log.h" +#include "tokenize.h" + +using namespace eis; + +FiniteTransmitionline::FiniteTransmitionline(fvalue c, fvalue r, unsigned int n): _C(c), _R(r), _n(n) +{ + if(n < 1) + { + Log(Log::WARN)<<__func__<<" n must be > 0 setting n to 4"; + _n = 4; + } + + subComponant = createTransmitionLine(_C, _R, _n); +} + +FiniteTransmitionline::FiniteTransmitionline(std::string paramStr) +{ + std::vector<std::string> tokens = tokenize(paramStr, ','); + if(tokens.size() < paramCount()) + { + Log(Log::WARN)<<"to few parameters in "<<__func__<<" parameter string: "<<paramStr; + _C = 1e-6; + _R = 1000; + _n = 4; + subComponant = createTransmitionLine(_C, _R, _n); + return; + } + else + { + try + { + _R = std::stod(tokens[0]); + _C = std::stod(tokens[1]); + _n = std::stod(tokens[2]); + subComponant = createTransmitionLine(_C, _R, _n); + } + catch(const std::invalid_argument& ia) + { + Log(Log::WARN)<<"Warning: cant parse parameter in "<<__func__<<" parameter: "<<tokens[0]<<'\n'; + _C = 1e3; + } + } +} + +FiniteTransmitionline::FiniteTransmitionline(const FiniteTransmitionline& in) +{ + _R = in._R; + _C = in._C; + _n = in._n; + subComponant = createTransmitionLine(_C, _R, _n); +} + +std::complex<fvalue> FiniteTransmitionline::execute(fvalue omega) +{ + if(subComponant) + { + return subComponant->execute(omega); + } + else + { + Log(Log::WARN)<<"Invalid transmitionline used"; + return std::complex<fvalue>(1, 0); + } +} + +std::vector<fvalue> FiniteTransmitionline::getParam() +{ + return std::vector<fvalue>({_R, _C, static_cast<fvalue>(_n)}); +} + +void FiniteTransmitionline::setParam(const std::vector<fvalue>& param) +{ + if(param.size() < paramCount()) + { + Log(Log::WARN)<<"invalid parameter list sent to "<<__func__<<'\n'; + return; + } + + _R = param[0]; + _C = param[1]; + _n = param[2]; + + if(param[2] < 1) + { + Log(Log::WARN)<<"invalid parameter list sent to "<<__func__<<" n must be > 1 "<<'\n'; + return; + } + + _n = param[2]; +} + +char FiniteTransmitionline::getComponantChar() const +{ + return FiniteTransmitionline::staticGetComponantChar(); +} + +size_t FiniteTransmitionline::paramCount() +{ + return 3; +} + +Componant* FiniteTransmitionline::createTransmitionLine(fvalue c, fvalue r, unsigned int n) +{ + Parallel* par = new Parallel; + par->componants.push_back(new Cap(c)); + par->componants.push_back(new Resistor(r)); + + for(unsigned int i = 0; i < n; ++i) + { + Serial* ser = new Serial; + ser->componants.push_back(new Resistor(r)); + ser->componants.push_back(par); + + par = new Parallel; + par->componants.push_back(ser); + par->componants.push_back(new Cap(c)); + } + + return par; +} + +FiniteTransmitionline::~FiniteTransmitionline() +{ + if(subComponant) + delete subComponant; +} diff --git a/inductor.cpp b/inductor.cpp index 1c06219..195a78a 100644 --- a/inductor.cpp +++ b/inductor.cpp @@ -60,3 +60,8 @@ size_t Inductor::paramCount() { return 1; } + +char Inductor::getComponantChar() const +{ + return staticGetComponantChar(); +} diff --git a/log.cpp b/log.cpp index 3079291..fc50c58 100644 --- a/log.cpp +++ b/log.cpp @@ -21,7 +21,7 @@ using namespace eis; -Log::Log(Level type) +Log::Log(Level type, bool endlineI): endline(endlineI) { msglevel = type; if(headers) @@ -32,7 +32,7 @@ Log::Log(Level type) Log::~Log() { - if(opened && endline) + if(opened && endline) { std::cout<<'\n'; } @@ -63,4 +63,3 @@ std::string Log::getLabel(Level level) bool Log::headers = false; Log::Level Log::level = WARN; -bool Log::endline = true; diff --git a/main.cpp b/main.cpp index 3d2c811..4e7b9eb 100644 --- a/main.cpp +++ b/main.cpp @@ -13,7 +13,7 @@ static void printComponants(eis::Model& model) eis::Log(eis::Log::DEBUG)<<"Compnants:"; for(eis::Componant* componant : model.getFlatComponants()) { - eis::Log(eis::Log::DEBUG)<<eis::Componant::getComponantChar(componant)<<"{"; + eis::Log(eis::Log::DEBUG)<<componant->getComponantChar()<<"{"; for(size_t i = 0; i < componant->paramCount(); ++i) { eis::Log(eis::Log::DEBUG)<<componant->getParam()[i]; diff --git a/model.cpp b/model.cpp index 6848fbc..033b41a 100644 --- a/model.cpp +++ b/model.cpp @@ -1,11 +1,14 @@ +#include <cstddef> #include <model.h> #include <iostream> #include <assert.h> +#include <vector> #include "tokenize.h" #include "cap.h" #include "resistor.h" #include "inductor.h" #include "constantphase.h" +#include "finitetr.h" #include "warburg.h" #include "paralellseriel.h" #include "log.h" @@ -79,10 +82,10 @@ Componant *Model::processBrackets(std::string& str, size_t& bracketCounter) std::string Model::getParamStr(const std::string& str, size_t index) { - if(str.size()-index < 3 || str[index+1] != '{') + if(static_cast<int64_t>(str.size())-index < 3 || str[index+1] != '{') { - Log(Log::DEBUG)<<"missing parameter for "<<str[index]; - return 0; + Log(Log::WARN)<<"missing parameter string for "<<str[index]; + return ""; } size_t end = opposingBraket(str, index, '}'); @@ -107,35 +110,58 @@ Componant *Model::processBracket(std::string& str) Log(Log::DEBUG)<<__func__<<" arg: "<<nodeStr[i]; switch(nodeStr[i]) { - case 'c': - case 'C': + case Cap::staticGetComponantChar(): + { componants.push_back(new Cap(getParamStr(nodeStr, i))); - i = opposingBraket(nodeStr, i, '}'); + size_t opposing = opposingBraket(nodeStr, i, '}'); + if(opposing != std::string::npos) + i = opposingBraket(nodeStr, i, '}'); break; - case 'r': - case 'R': + } + case Resistor::staticGetComponantChar(): + { componants.push_back(new Resistor(getParamStr(nodeStr, i))); - i = opposingBraket(nodeStr, i, '}'); + size_t opposing = opposingBraket(nodeStr, i, '}'); + if(opposing != std::string::npos) + i = opposingBraket(nodeStr, i, '}'); break; - case 'l': - case 'L': + } + case Inductor::staticGetComponantChar(): + { componants.push_back(new Inductor(getParamStr(nodeStr, i))); - i = opposingBraket(nodeStr, i, '}'); + size_t opposing = opposingBraket(nodeStr, i, '}'); + if(opposing != std::string::npos) + i = opposingBraket(nodeStr, i, '}'); break; - case 'p': - case 'P': + } + case Cpe::staticGetComponantChar(): + { componants.push_back(new Cpe(getParamStr(nodeStr, i))); - i = opposingBraket(nodeStr, i, '}'); + size_t opposing = opposingBraket(nodeStr, i, '}'); + if(opposing != std::string::npos) + i = opposingBraket(nodeStr, i, '}'); break; - case 'w': - case 'W': + } + case Warburg::staticGetComponantChar(): + { componants.push_back(new Warburg(getParamStr(nodeStr, i))); - i = opposingBraket(nodeStr, i, '}'); + size_t opposing = opposingBraket(nodeStr, i, '}'); + if(opposing != std::string::npos) + i = opposingBraket(nodeStr, i, '}'); + break; + } + case FiniteTransmitionline::staticGetComponantChar(): + { + componants.push_back(new FiniteTransmitionline(getParamStr(nodeStr, i))); + size_t opposing = opposingBraket(nodeStr, i, '}'); + if(opposing != std::string::npos) + i = opposingBraket(nodeStr, i, '}'); break; + } case '{': i = opposingBraket(nodeStr, i, '}'); case '}': - Log(Log::WARN)<<"stray "<<nodeStr[i]<<" in model string"; + Log(Log::WARN)<<getModelStr()<<" stray "<<nodeStr[i]<<" in model string"; break; case '0' ... '9': { @@ -191,8 +217,11 @@ Model::~Model() delete _model; } -DataPoint Model::execute(fvalue omega) +DataPoint Model::execute(fvalue omega, Componant* model) { + if(!model) + model = _model; + if(_model) { DataPoint dataPoint; @@ -207,13 +236,13 @@ DataPoint Model::execute(fvalue omega) return DataPoint({std::complex<fvalue>(0,0), 0}); } -void Model::addComponantToFlat(Componant* componant) +void Model::addComponantToFlat(Componant* componant, std::vector<Componant*>* flatComponants) { Parallel* paralell = dynamic_cast<Parallel*>(componant); if(paralell) { for(Componant* element : paralell->componants) - addComponantToFlat(element); + addComponantToFlat(element, flatComponants); return; } @@ -221,24 +250,36 @@ void Model::addComponantToFlat(Componant* componant) if(serial) { for(Componant* element : serial->componants) - addComponantToFlat(element); + addComponantToFlat(element, flatComponants); return; } - _flatComponants.push_back(componant); + flatComponants->push_back(componant); } -std::vector<Componant*> Model::getFlatComponants() +std::vector<Componant*> Model::getFlatComponants(Componant *model) { - if(!_flatComponants.empty()) - return _flatComponants; + if(model == nullptr || model == _model) + { + if(!_flatComponants.empty()) + return _flatComponants; - addComponantToFlat(_model); - return getFlatComponants(); + addComponantToFlat(_model, &_flatComponants); + return getFlatComponants(); + } + else + { + std::vector<Componant*> flatComponants; + addComponantToFlat(model, &flatComponants); + return flatComponants; + } } -std::vector<DataPoint> Model::executeSweep(const Range& omega) +std::vector<DataPoint> Model::executeSweep(const Range& omega, Componant* model) { + if(!model) + model = _model; + std::vector<DataPoint> results; results.reserve(omega.count); @@ -249,7 +290,7 @@ std::vector<DataPoint> Model::executeSweep(const Range& omega) for(size_t i = 0; i < omega.count; ++i) { - results.push_back(execute(currOmega)); + results.push_back(execute(currOmega, model)); currOmega+=step; } } @@ -262,13 +303,27 @@ std::vector<DataPoint> Model::executeSweep(const Range& omega) for(size_t i = 0; i < omega.count; ++i) { - results.push_back(execute(pow(10, currOmegaL))); + results.push_back(execute(pow(10, currOmegaL), model)); currOmegaL+=step; } } return results; } +std::vector<DataPoint> Model::executeParamByIndexC(const std::vector<Range>& componantRanges, const Range& omega, size_t index) +{ + std::vector<fvalue> parameters = getSweepParamByIndex(componantRanges, index); + + Componant* model = Componant::copy(_model); + setFlatParameters(parameters, model); + + std::vector<DataPoint> data = executeSweep(omega, model); + + delete model; + + return data; +} + std::vector<DataPoint> Model::executeParamByIndex(const std::vector<Range>& componantRanges, const Range& omega, size_t index) { std::vector<fvalue> parameters = getSweepParamByIndex(componantRanges, index); @@ -306,25 +361,9 @@ bool Model::executeParamSweep(const std::vector<Range>& componantRanges, const R std::function<void(std::vector<DataPoint>&, const std::vector<fvalue>&)> dataCb) { size_t parametersCount = getFlatParametersCount(); - if(componantRanges.size() != parametersCount) - { - Log(Log::ERROR)<<"a parameter range must be provided for eatch componant parameter"; - return false; - } - for(size_t i = 0; i < parametersCount; ++i) - { - if(componantRanges[i].count == 0 || (componantRanges[i].count < 2 && componantRanges[i].start != componantRanges[i].end)) - { - Log(Log::ERROR)<<"paramter range must specify at least one paramter point if only one paramer point is specified start and end must be the same"; - return false; - } - else if(componantRanges[i].start > componantRanges[i].end) - { - Log(Log::ERROR)<<"paramter range end-start must be positive"; - return false; - } - } + if(!checkParameterRanges(componantRanges)) + return false; size_t stepsRequired = getRequiredStepsForSweeps(componantRanges); @@ -344,11 +383,14 @@ bool Model::executeParamSweep(const std::vector<Range>& componantRanges, const R return true; } -bool Model::setFlatParameters(const std::vector<fvalue>& parameters) +bool Model::setFlatParameters(const std::vector<fvalue>& parameters, Componant* model) { if(parameters.size() != getFlatParametersCount()) return false; + if(!model) + model = _model; + size_t i = 0; for(Componant* componant : getFlatComponants()) { @@ -361,10 +403,26 @@ bool Model::setFlatParameters(const std::vector<fvalue>& parameters) return true; } -std::vector<fvalue> Model::getFlatParameters() + +Componant* Model::flatParameterToFlatComponant(size_t parameterIndex) +{ + size_t i = 0; + for(Componant* componant : getFlatComponants()) + { + i += componant->paramCount(); + if(i > parameterIndex) + return componant; + } + return nullptr; +} + +std::vector<fvalue> Model::getFlatParameters(Componant *model) { + if(!model) + model = _model; + std::vector<fvalue> params; - std::vector<Componant*> componants = getFlatComponants(); + std::vector<Componant*> componants = getFlatComponants(model); for(Componant* componant : componants) { for(fvalue param : componant->getParam()) @@ -402,3 +460,54 @@ std::string Model::getModelStr() } return output; } + +bool Model::checkParameterRanges(const std::vector<eis::Range> ranges, Componant* model) +{ + if(!model) + model = _model; + + if(!model) + { + Log(Log::ERROR)<<"model not ready"; + return false; + } + + size_t parametersCount = getFlatParametersCount(); + std::vector<Componant*> flatComponants = getFlatComponants(model); + + if(ranges.size() != parametersCount) + { + Log(Log::ERROR)<<"a parameter range must be provided for eatch componant parameter"; + return false; + } + + for(size_t i = 0; i < parametersCount; ++i) + { + if(ranges[i].count == 0 || (ranges[i].count < 2 && ranges[i].start != ranges[i].end)) + { + Log(Log::ERROR)<<getModelStr()<<" paramter range must specify at least one paramter point if" + <<"one paramer point is specified start and end must be the same"; + return false; + } + else if(ranges[i].start > ranges[i].end) + { + Log(Log::ERROR)<<getModelStr()<<" paramter range end-start must be positive"; + return false; + } + else if(ranges[i].type != 'x' && ranges[i].type != flatParameterToFlatComponant(i)->getComponantChar()) + { + Log(Log::ERROR)<<getModelStr()<<" componnant "<<i<<"'s range is of invalid type " + <<ranges[i].type<<". expected "<<flatComponants[i]->getComponantChar()<<'\n' + <<"Expected order:"; + + for(const Componant* componant : flatComponants) + { + Log(Log::ERROR, false)<<componant->getComponantChar(); + } + std::cout<<std::endl; + + return false; + } + } + return true; +} diff --git a/options.h b/options.h index 8cd8000..c0b1413 100644 --- a/options.h +++ b/options.h @@ -19,7 +19,7 @@ static struct argp_option options[] = {"model", 'm', "[STRING]", 0, "set model string" }, {"omega", 'o', "[START-END]", 0, "set omega range" }, {"omegasteps", 'c', "[COUNT]", 0, "set omega range steps" }, - {"log", 'l', 0, 0, "use logarithmic steps" }, + {"linear", 'l', 0, 0, "use linear instead of logarithmic steps" }, {"normalize", 'n', 0, 0, "normalize values" }, {"reduce", 'r', 0, 0, "reduce values to \"interesting\" range" }, {"hz", 'h', 0, 0, "freqency values as temporal frequency instead of angular frequency"}, @@ -43,7 +43,7 @@ struct Config bool hertz = false; bool invert = false; - Config(): omegaRange(1, 1001, 1) + Config(): omegaRange(1, 1001, 1, true) {} }; @@ -70,7 +70,7 @@ parse_opt (int key, char *arg, struct argp_state *state) config->modelStr.assign(arg); break; case 'l': - config->omegaRange.log = true; + config->omegaRange.log = false; break; case 'n': config->normalize = true; diff --git a/paralellseriel.cpp b/paralellseriel.cpp index 458675b..b9c681c 100644 --- a/paralellseriel.cpp +++ b/paralellseriel.cpp @@ -35,6 +35,11 @@ std::complex<fvalue> Parallel::execute(fvalue omega) return std::complex<fvalue>(1,0)/accum; } +char Parallel::getComponantChar() const +{ + return staticGetComponantChar(); +} + Serial::Serial(std::vector<Componant*> componantsIn): componants(componantsIn) { } @@ -67,3 +72,8 @@ std::complex<fvalue> Serial::execute(fvalue omega) } return accum; } + +char Serial::getComponantChar() const +{ + return staticGetComponantChar(); +} diff --git a/resistor.cpp b/resistor.cpp index eb487bc..c83b9e2 100644 --- a/resistor.cpp +++ b/resistor.cpp @@ -59,3 +59,8 @@ size_t Resistor::paramCount() { return 1; } + +char Resistor::getComponantChar() const +{ + return staticGetComponantChar(); +} diff --git a/test.cpp b/test.cpp index 92a69f4..a403452 100644 --- a/test.cpp +++ b/test.cpp @@ -73,7 +73,7 @@ void printComponants(eis::Model& model) eis::Log(eis::Log::DEBUG)<<"Compnants:"; for(eis::Componant* componant : model.getFlatComponants()) { - eis::Log(eis::Log::DEBUG)<<eis::Componant::getComponantChar(componant)<<"{"; + eis::Log(eis::Log::DEBUG)<<componant->getComponantChar()<<"{"; for(size_t i = 0; i < componant->paramCount(); ++i) { eis::Log(eis::Log::DEBUG)<<componant->getParam()[i]; diff --git a/warburg.cpp b/warburg.cpp index 2dd1f3a..c4e30f2 100644 --- a/warburg.cpp +++ b/warburg.cpp @@ -17,7 +17,7 @@ Warburg::Warburg(std::string paramStr) std::vector<std::string> tokens = tokenize(paramStr, ','); if(tokens.size() < 1) { - Log(Log::WARN)<<"to few parameters in "<<__func__<<" parameter string: "<<paramStr<<'\n'; + Log(Log::WARN)<<"to few parameters in "<<__func__<<" parameter string: "<<paramStr; return; } else @@ -59,3 +59,8 @@ size_t Warburg::paramCount() { return 1; } + +char Warburg::getComponantChar() const +{ + return staticGetComponantChar(); +} -- GitLab