From c4384d0234386fb53f126258cd257554c5dc19f7 Mon Sep 17 00:00:00 2001
From: Carl Klemm <carl@uvos.xyz>
Date: Wed, 20 Apr 2022 11:58:36 +0200
Subject: [PATCH] Implement Warburg element Implement distructors

---
 CMakeLists.txt  |  1 +
 cap.h           |  1 +
 componant.h     |  1 +
 constantphase.h |  1 +
 main.cpp        |  6 +++---
 model.cpp       | 27 +++++++++++++++++++++--
 model.h         |  3 +++
 resistor.h      |  1 +
 warburg.cpp     | 57 +++++++++++++++++++++++++++++++++++++++++++++++++
 warburg.h       | 19 +++++++++++++++++
 10 files changed, 112 insertions(+), 5 deletions(-)
 create mode 100644 warburg.cpp
 create mode 100644 warburg.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 81b2794..533ff6f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,6 +7,7 @@ set(SRC_FILES
 	cap.cpp
 	resistor.cpp
 	constantphase.cpp
+	warburg.cpp
 	model.cpp
 	tokenize.cpp
 )
diff --git a/cap.h b/cap.h
index ad7cd73..e8c72bd 100644
--- a/cap.h
+++ b/cap.h
@@ -15,4 +15,5 @@ public:
 	virtual std::vector<double> getParam() override;
 	virtual void setParam(const std::vector<double>& param) override;
 	virtual size_t paramCount() override;
+	virtual ~Cap() = default;
 };
diff --git a/componant.h b/componant.h
index b93967f..7f0aa42 100644
--- a/componant.h
+++ b/componant.h
@@ -18,4 +18,5 @@ class Componant
 		};
 		virtual void setParam(const std::vector<double>& param){};
 		virtual size_t paramCount(){return 0;}
+		virtual ~Componant() = default;
 };
diff --git a/constantphase.h b/constantphase.h
index 81804ec..8092832 100644
--- a/constantphase.h
+++ b/constantphase.h
@@ -16,4 +16,5 @@ public:
 	virtual std::vector<double> getParam() override;
 	virtual void setParam(const std::vector<double>& param) override;
 	virtual size_t paramCount() override;
+	virtual ~Cpe() = default;
 };
diff --git a/main.cpp b/main.cpp
index 064b8c4..74ebc3e 100644
--- a/main.cpp
+++ b/main.cpp
@@ -6,7 +6,7 @@
 
 void runSingle()
 {
-	std::string modelStr("r{20e3}p{1e-7, 0.9}");
+	std::string modelStr("w{20e3}p{1e-7, 0.9}");
 
 	std::vector<Model::DataPoint> results;
 
@@ -47,7 +47,7 @@ void sweepCb(std::vector<Model::DataPoint>& data, const std::vector<double>& par
 
 void runSweep()
 {
-	std::string modelStr("r{20e3}p{1e-7, 0.9}");
+	std::string modelStr("w{20e3}p{1e-7, 0.9}");
 	std::vector<Model::DataPoint> results;
 
 	Model model(modelStr);
@@ -70,6 +70,6 @@ void runSweep()
 int main(int argc, char** argv)
 {
 	runSingle();
-	runSweep();
+	//runSweep();
 	return 0;
 }
diff --git a/model.cpp b/model.cpp
index fd167ff..1b510ec 100644
--- a/model.cpp
+++ b/model.cpp
@@ -4,11 +4,18 @@
 #include "cap.h"
 #include "resistor.h"
 #include "constantphase.h"
+#include "warburg.h"
 
 Model::Paralell::Paralell(std::vector<Componant*> componantsIn): componants(componantsIn)
 {
 }
 
+Model::Paralell::~Paralell()
+{
+	for(Componant* componant : componants)
+		delete componant;
+}
+
 std::complex<double> Model::Paralell::execute(double omega)
 {
 	std::complex<double> accum(0,0);
@@ -23,6 +30,12 @@ Model::Serial::Serial(std::vector<Componant*> componantsIn): componants(componan
 {
 }
 
+Model::Serial::~Serial()
+{
+	for(Componant* componant : componants)
+		delete componant;
+}
+
 std::complex<double> Model::Serial::execute(double omega)
 {
 	std::complex<double> accum(0,0);
@@ -145,6 +158,11 @@ Componant *Model::processBracket(std::string& str)
 					componants.push_back(new Cpe(getParamStr(nodeStr, i)));
 					i = opposingBraket(nodeStr, i, '}');
 					break;
+				case 'w':
+				case 'W':
+					componants.push_back(new Warburg(getParamStr(nodeStr, i)));
+					i = opposingBraket(nodeStr, i, '}');
+					break;
 				case '{':
 					i = opposingBraket(nodeStr, i, '}');
 				case '}':
@@ -184,6 +202,11 @@ Model::Model(const std::string& str): _modelStr(str)
 	_model = processBrackets(strCpy, bracketCounter);
 }
 
+Model::~Model()
+{
+	delete _model;
+}
+
 Model::DataPoint Model::execute(double omega)
 {
 	if(_model)
@@ -280,7 +303,6 @@ bool Model::sweepParams(const std::vector<Range>& componantRanges, const Range&
 		stepSize[i] = (componantRanges[i].end - componantRanges[i].start)/componantRanges[i].count;
 	}
 
-
 	std::cout<<"Executing sweep. Steps requried: "<<stepsRequired<<std::endl;
 
 	for(size_t i = 0; i < stepsRequired; ++i)
@@ -329,11 +351,12 @@ 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';
+	if(dynamic_cast<Warburg*>(componant))
+		return 'w';
 
 	return 'x';
 }
diff --git a/model.h b/model.h
index da11a0b..5707652 100644
--- a/model.h
+++ b/model.h
@@ -31,6 +31,7 @@ private:
 		std::vector<Componant*> componants;
 
 		Paralell(std::vector<Componant*> componantsIn = std::vector<Componant*>());
+		~Paralell();
 		virtual std::complex<double> execute(double omaga) override;
 	};
 
@@ -40,6 +41,7 @@ private:
 		std::vector<Componant*> componants;
 
 		Serial(std::vector<Componant*> componantsIn = std::vector<Componant*>());
+		~Serial();
 		virtual std::complex<double> execute(double omaga) override;
 	};
 
@@ -58,6 +60,7 @@ private:
 
 public:
 	Model(const std::string& str);
+	~Model();
 	DataPoint execute(double omaga);
 	std::vector<DataPoint> sweep(const Range& omega);
 	bool sweepParams(const std::vector<Range>& componantRanges, const Range& omega, std::function<void(std::vector<DataPoint>&, const std::vector<double>&)> dataCb);
diff --git a/resistor.h b/resistor.h
index aa894cb..d21a20e 100644
--- a/resistor.h
+++ b/resistor.h
@@ -14,4 +14,5 @@ public:
 	virtual std::vector<double> getParam() override;
 	virtual void setParam(const std::vector<double>& param) override;
 	virtual size_t paramCount() override;
+	virtual ~Resistor() = default;
 };
diff --git a/warburg.cpp b/warburg.cpp
new file mode 100644
index 0000000..96bb1e5
--- /dev/null
+++ b/warburg.cpp
@@ -0,0 +1,57 @@
+#include "warburg.h"
+#include "tokenize.h"
+#include <cstdlib>
+#include <math.h>
+
+Warburg::Warburg(double a): _A(a)
+{
+
+}
+
+Warburg::Warburg(std::string paramStr)
+{
+	std::vector<std::string> tokens = tokenize(paramStr, ',');
+	if(tokens.size() < 1)
+	{
+		std::cout<<"Warning: to few parameters in "<<__func__<<" parameter string: "<<paramStr<<'\n';
+		return;
+	}
+	else
+	{
+		try
+		{
+			_A = std::stod(tokens[0]);
+		}
+		catch(const std::invalid_argument& ia)
+		{
+			std::cout<<"Warning: cant parse parameter in "<<__func__<<" parameter: "<<tokens[0]<<'\n';
+		}
+	}
+}
+
+std::complex<double> Warburg::execute(double omega)
+{
+	double N = _A/(sqrt(omega));
+	return std::complex<double>(N, 0-N);
+}
+
+std::vector<double> Warburg::getParam()
+{
+	return std::vector<double>({_A});
+}
+
+void Warburg::setParam(const std::vector<double>& param)
+{
+	if(param.size() != paramCount())
+	{
+		std::cout<<"Warning: invalid parameter list sent to "<<__func__<<'\n';
+		return;
+	}
+
+	_A = param[0];
+}
+
+size_t Warburg::paramCount()
+{
+	return 1;
+}
diff --git a/warburg.h b/warburg.h
new file mode 100644
index 0000000..f9f4011
--- /dev/null
+++ b/warburg.h
@@ -0,0 +1,19 @@
+#pragma once
+#include <complex>
+#include <string>
+#include <vector>
+#include "componant.h"
+
+class Warburg: public Componant
+{
+private:
+	double _A = 2e4;
+public:
+	Warburg(std::string paramStr);
+	Warburg(double a = 2e4);
+	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;
+	virtual ~Warburg() = default;
+};
-- 
GitLab