diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f33bfef96b3b85f81313ad10d0995deefc0d2cb..a390c51a19b34cc6ee9706458789efc8a58b3f42 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 61e9041dabc5c0ad680df5701b7c906bbd173dd8..19933dd431e7b57c174d22cdd558ad978fad52f5 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 7ea0e0b4bdb848499f95013cba84e35ba96921bf..f0e29eb89fea1f199c6ee98c4b9b2779fb9aa42f 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 6022ba85d52da43f1931e8f8e4cdc7db6539b641..834a884d64d9526cc5f0ff12cb3f6e4b263ede19 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 d394f833b3d05a23553fa4baa34d893195fb351e..e0e66c4ddd70504841c7fbe8e43d23b9edf5cbb5 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 141049e50eb674a472e3dd74ebc72295d31e649f..eb5ca6de542ed39050e045ac2ff9ea8daa9eca52 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 11587171c525bd7200310251423969943d4cec28..0706e26e7f20f6ccfef77c5194fe7cf3d58f443e 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 43c6e3cdf838abe0ad77493a35e5a6c223f9b0c0..7c0b5947cd9d80e44ba87097466a51370bdb383d 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 0000000000000000000000000000000000000000..fbaf35d7f7be703e1d8c254993e2ea3597f8c1da --- /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 8edba47b832863251913472f74c74a201cffab86..a2634625520fff3c09abfd1da05ec125b0bd0fdd 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 e07cb23e8ad7c9b935d30744c024fb60c509e0c3..d4240ca1087aeb5a92837cf6359d2706662fcf42 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 0a654b39e58c118227502b0101ca21a6325987bd..7f47ccd27354ac209458c64a8c2e9695ab875fe8 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 e764c970083106ec9ad887bae40ee4bc72f3c74e..1a63dbf3523ad80de052f8975fe7a7f238c54dfd 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 42bc4d68eb64cacddd4b1248affffa4c1b15e525..f9d412da40741fe35f7943126aeb623de3c21700 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 0974d9949933a6d39afacdd04d691db3ff9e816c..7fdd8b86bc7bb34161ef8b86256bc756abbc3ddc 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 0000000000000000000000000000000000000000..a69487a496717b7204b995ae77f5550a2ed0e965 --- /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 1c06219a802438cb7476f40a3a9b5c7989b3c1fe..195a78a4766e30fcff56a78efbf046e856e1837d 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 307929146c813cc8543443a807497c3fe2b66b5e..fc50c5889344ebd1f594778e957d98c9d4012ca5 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 3d2c811ed3e282731a66f495954d3f4d15e8d92d..4e7b9ebc0a9f94639e57cfb91d7309c3ac1c8645 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 6848fbc92501e3fbf6c22c16475429f4187ae598..033b41af6ec66d69669e347e054fbacace20b272 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 8cd800030b7be43ca263a0603615bae75de87a46..c0b14138f8ffcb1b1fbbc87bb84d3f3d2859f95a 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 458675b300bf256b49344fee74b4d64e9f3c8411..b9c681cf17e28577d38431dd1c6b424f1bfd07f8 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 eb487bcd4398c9dedd1cc5a5f60ffca731b0dccd..c83b9e2e0e48d8d4cb7c3a4fda022b78b4b98e0b 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 92a69f40f7bca4ca168db0af6d4eb055b6cf954b..a4034523f8e47237706d741dd1804148bb763d21 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 2dd1f3aaae42cc63073e968363a4a619741e425f..c4e30f2d6f3b29cd05a7ad4f2b63e4be1c29d438 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(); +}