From 9301fdeb60185d8c61897948f0df6690d4bc85e3 Mon Sep 17 00:00:00 2001 From: Carl Klemm <carl@uvos.xyz> Date: Tue, 19 Apr 2022 12:31:59 +0200 Subject: [PATCH] Constant phase element added --- CMakeLists.txt | 11 +++++++-- cap.cpp | 5 ++++ cap.h | 1 + componant.h | 1 + constantphase.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++ constantphase.h | 19 ++++++++++++++ main.cpp | 19 +++++++++++--- model.cpp | 50 +++++++++++++++++++++++++++++++++++++ model.h | 2 ++ resistor.cpp | 5 ++++ resistor.h | 1 + 11 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 constantphase.cpp create mode 100644 constantphase.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b6e12f..81b2794 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,14 @@ cmake_minimum_required(VERSION 3.20) project(ehigeneratorsa) -set(SRC_FILES main.cpp cap.cpp resistor.cpp model.cpp tokenize.cpp) +set(SRC_FILES + main.cpp + cap.cpp + resistor.cpp + constantphase.cpp + model.cpp + tokenize.cpp +) find_package(PkgConfig REQUIRED) pkg_check_modules(SPICE REQUIRED ngspice) @@ -10,6 +17,6 @@ pkg_check_modules(SPICE REQUIRED ngspice) add_executable(${PROJECT_NAME} ${SRC_FILES}) target_link_libraries(${PROJECT_NAME} ${SPICE_LIBRARIES}) target_include_directories(${PROJECT_NAME} PUBLIC ${SPICE_CFLAGS} .) -set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-std=c++20 -Wall -O0 -march=native -g" LINK_FLAGS "-flto") +set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-std=c++20 -Wall -O3 -march=native -g" LINK_FLAGS "-flto") install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) diff --git a/cap.cpp b/cap.cpp index 447d564..0bed200 100644 --- a/cap.cpp +++ b/cap.cpp @@ -51,3 +51,8 @@ void Cap::setParam(const std::vector<double>& param) _C = param[0]; } + +size_t Cap::paramCount() +{ + return 1; +} diff --git a/cap.h b/cap.h index 95c7bb2..ad7cd73 100644 --- a/cap.h +++ b/cap.h @@ -14,4 +14,5 @@ public: virtual std::complex<double> execute(double omega) override; virtual std::vector<double> getParam() override; virtual void setParam(const std::vector<double>& param) override; + virtual size_t paramCount() override; }; diff --git a/componant.h b/componant.h index c5f3a53..b93967f 100644 --- a/componant.h +++ b/componant.h @@ -17,4 +17,5 @@ class Componant return std::vector<double>(); }; virtual void setParam(const std::vector<double>& param){}; + virtual size_t paramCount(){return 0;} }; diff --git a/constantphase.cpp b/constantphase.cpp new file mode 100644 index 0000000..fa86aa0 --- /dev/null +++ b/constantphase.cpp @@ -0,0 +1,63 @@ +#include "constantphase.h" +#include "tokenize.h" +#include <cstdlib> +#include <math.h> + +Cpe::Cpe(double q, double alpha): _Q(q), _alpha(alpha) +{ + +} + +Cpe::Cpe(std::string paramStr) +{ + std::vector<std::string> tokens = tokenize(paramStr, ','); + if(tokens.size() < 2) + { + std::cout<<"Warning: to few parameters in "<<__func__<<" parameter string: "<<paramStr<<'\n'; + _Q = 1e-7; + _alpha = 0.9; + return; + } + else + { + try + { + _Q = std::stod(tokens[0]); + _alpha = std::stod(tokens[1]); + } + catch(const std::invalid_argument& ia) + { + std::cout<<"Warning: cant parse parameter in "<<__func__<<" parameter: "<<tokens[0]<<'\n'; + _Q = 1e-7; + _alpha = 0.9; + } + } +} + +std::complex<double> Cpe::execute(double omega) +{ + return std::complex<double>((1.0/(_Q*pow(omega, _alpha)))*cos((M_PI/2)*_alpha), + 0-(1.0/(_Q*pow(omega, _alpha)))*sin((M_PI/2)*_alpha)); +} + +std::vector<double> Cpe::getParam() +{ + return std::vector<double>({_Q, _alpha}); +} + +void Cpe::setParam(const std::vector<double>& param) +{ + if(param.size() < 2) + { + std::cout<<"Warning: invalid parameter list sent to "<<__func__<<'\n'; + return; + } + + _Q = param[0]; + _alpha = param[1]; +} + +size_t Cpe::paramCount() +{ + return 2; +} diff --git a/constantphase.h b/constantphase.h new file mode 100644 index 0000000..81804ec --- /dev/null +++ b/constantphase.h @@ -0,0 +1,19 @@ +#pragma once +#include <complex> +#include <string> +#include <vector> +#include "componant.h" + +class Cpe: public Componant +{ +private: + double _Q; + double _alpha; +public: + Cpe(std::string paramStr); + Cpe(double q = 1e-7, double alpha = 0.9); + virtual std::complex<double> execute(double omega) override; + virtual std::vector<double> getParam() override; + virtual void setParam(const std::vector<double>& param) override; + virtual size_t paramCount() override; +}; diff --git a/main.cpp b/main.cpp index 7f83be7..65d0be4 100644 --- a/main.cpp +++ b/main.cpp @@ -6,18 +6,31 @@ double omegafn(size_t i) { - return i*10; + return i*10000; } int main(int argc, char** argv) { - std::string modelStr("r{1e3}-(c{1e-6}r{1e3})"); + std::string modelStr("r{20e3}p{1e-7, 0.9}"); std::vector<Model::DataPoint> results; Model model(modelStr); + std::cout<<"Compnants: \n"; + for(Componant* componant : model.getFlatComponants()) + { + std::cout<<Model::getComponantChar(componant)<<"{"; + for(size_t i = 0; i < componant->paramCount(); ++i) + { + std::cout<<componant->getParam()[i]; + if(i != componant->paramCount()-1) + std::cout<<", "; + } + std::cout<<"}\n"; + } + auto start = std::chrono::high_resolution_clock::now(); - for(size_t i = 0; i < 50; ++i) + for(size_t i = 0; i < 101; ++i) results.push_back(model.execute(omegafn(i))); auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); diff --git a/model.cpp b/model.cpp index 375ce27..c7b80d1 100644 --- a/model.cpp +++ b/model.cpp @@ -3,6 +3,7 @@ #include "tokenize.h" #include "cap.h" #include "resistor.h" +#include "constantphase.h" Model::Paralell::Paralell(std::vector<Componant*> componantsIn): componants(componantsIn) { @@ -139,6 +140,11 @@ Componant *Model::processBracket(std::string& str) componants.push_back(new Resistor(getParamStr(nodeStr, i))); i = opposingBraket(nodeStr, i, '}'); break; + case 'p': + case 'P': + componants.push_back(new Cpe(getParamStr(nodeStr, i))); + i = opposingBraket(nodeStr, i, '}'); + break; case '{': i = opposingBraket(nodeStr, i, '}'); case '}': @@ -193,3 +199,47 @@ Model::DataPoint Model::execute(double omega) } return DataPoint({std::complex<double>(0,0), 0}); } + +void Model::addComponantToFlat(Componant* componant) +{ + Paralell* paralell = dynamic_cast<Paralell*>(componant); + if(paralell) + { + for(Componant* element : paralell->componants) + addComponantToFlat(element); + return; + } + + Serial* serial = dynamic_cast<Serial*>(componant); + if(serial) + { + for(Componant* element : serial->componants) + addComponantToFlat(element); + return; + } + + _flatComponants.push_back(componant); +} + +std::vector<Componant*> Model::getFlatComponants() +{ + if(!_flatComponants.empty()) + return _flatComponants; + + addComponantToFlat(_model); + return getFlatComponants(); +} + +char Model::getComponantChar(Componant* componant) +{ + if(dynamic_cast<Resistor*>(componant)) + return 'r'; + + if(dynamic_cast<Cap*>(componant)) + return 'c'; + + if(dynamic_cast<Cpe*>(componant)) + return 'p'; + + return 'x'; +} diff --git a/model.h b/model.h index bee488e..18b3e3a 100644 --- a/model.h +++ b/model.h @@ -38,6 +38,7 @@ 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); private: Componant *_model = nullptr; @@ -50,4 +51,5 @@ public: DataPoint execute(double omaga); std::string getModelStr(); std::vector<Componant*> getFlatComponants(); + static char getComponantChar(Componant* componant); }; diff --git a/resistor.cpp b/resistor.cpp index d9b33b3..d81c17f 100644 --- a/resistor.cpp +++ b/resistor.cpp @@ -50,3 +50,8 @@ void Resistor::setParam(const std::vector<double>& param) _R = param[0]; } + +size_t Resistor::paramCount() +{ + return 1; +} diff --git a/resistor.h b/resistor.h index 0f9d2cd..aa894cb 100644 --- a/resistor.h +++ b/resistor.h @@ -13,4 +13,5 @@ public: virtual std::complex<double> execute(double omega) override; virtual std::vector<double> getParam() override; virtual void setParam(const std::vector<double>& param) override; + virtual size_t paramCount() override; }; -- GitLab