From b15c933a42e9a1cf1846803db88e0c3148108f89 Mon Sep 17 00:00:00 2001 From: Marvin Tollnitsch Date: Mon, 16 Sep 2024 10:13:05 +0200 Subject: [PATCH] Add test circuits for new diode model + add .cpp and python notebook for first diode example circuit + add python pybind notebook for second diode example circuit * modify "dpsim/examples/cxx/CMakeLists.cpp" to include .cpp of first diode example circuit Signed-off-by: Marvin Tollnitsch --- dpsim/examples/cxx/CMakeLists.txt | 1 + .../cxx/Circuits/EMT_Ph1_Diode_test.cpp | 59 ++++++++ .../Notebooks/Circuits/EMT_Ph1_Diode.ipynb | 125 ++++++++++++++++ .../Circuits/EMT_Ph1_VS_R1_Diode.ipynb | 139 ++++++++++++++++++ 4 files changed, 324 insertions(+) create mode 100644 dpsim/examples/cxx/Circuits/EMT_Ph1_Diode_test.cpp create mode 100644 examples/Notebooks/Circuits/EMT_Ph1_Diode.ipynb create mode 100644 examples/Notebooks/Circuits/EMT_Ph1_VS_R1_Diode.ipynb diff --git a/dpsim/examples/cxx/CMakeLists.txt b/dpsim/examples/cxx/CMakeLists.txt index dba9ec1117..f5ec131767 100644 --- a/dpsim/examples/cxx/CMakeLists.txt +++ b/dpsim/examples/cxx/CMakeLists.txt @@ -33,6 +33,7 @@ set(CIRCUIT_SOURCES #Circuits/EMT_ResVS_RL_Switch.cpp Circuits/EMT_VSI.cpp Circuits/EMT_PiLine.cpp + Circuits/EMT_Ph1_Diode_test.cpp # EMT examples with PF initialization Circuits/EMT_Slack_PiLine_PQLoad_with_PF_Init.cpp diff --git a/dpsim/examples/cxx/Circuits/EMT_Ph1_Diode_test.cpp b/dpsim/examples/cxx/Circuits/EMT_Ph1_Diode_test.cpp new file mode 100644 index 0000000000..d078c1e45a --- /dev/null +++ b/dpsim/examples/cxx/Circuits/EMT_Ph1_Diode_test.cpp @@ -0,0 +1,59 @@ +#include "../Examples.h" +#include + +using namespace DPsim; +using namespace CPS::EMT; + +void EMT_Ph1_Diode() { + // Define simulation scenario + Real timeStep = 0.0001; + Real finalTime = 0.1; + String simName = "EMT_Ph1_Diode_test"; + Logger::setLogDir("logs/" + simName); + + // Nodes + auto n1 = SimNode::make("n1", PhaseType::Single); + auto n2 = SimNode::make("n1", PhaseType::Single); + + // Components + + auto vs0 = Ph1::VoltageSource::make("vs0"); + vs0->setParameters(CPS::Complex(1., 0.), 50.0); + + auto load = CPS::EMT::Ph1::Resistor::make("Load"); + load->setParameters(10.); + + auto diode = Ph1::Diode::make("Diode"); + + // Topology + load->connect(SimNode::List{n1, n2}); + + diode->connect(SimNode::List{n2, SimNode::GND}); //SimNode::GND, n2 + + vs0->connect(SimNode::List{SimNode::GND, n1}); + + // Define system topology + auto sys = SystemTopology(50, SystemNodeList{n1, n2}, + SystemComponentList{load, vs0, diode}); + + // Logging + auto logger = DataLogger::make(simName); + logger->logAttribute("I_Diode", diode->attribute("i_intf")); + logger->logAttribute("V_Diode", diode->attribute("v_intf")); + + Simulation sim(simName, Logger::Level::info); + sim.doInitFromNodesAndTerminals(true); + sim.setSystem(sys); + sim.addLogger(logger); + sim.setDomain(Domain::EMT); + sim.setSolverType(Solver::Type::ITERATIVEMNA); + sim.setDirectLinearSolverConfiguration(DirectLinearSolverConfiguration()); + sim.setTimeStep(timeStep); + sim.setFinalTime(finalTime); + sim.run(); +} + +int main() { + EMT_Ph1_Diode(); + return 0; +} \ No newline at end of file diff --git a/examples/Notebooks/Circuits/EMT_Ph1_Diode.ipynb b/examples/Notebooks/Circuits/EMT_Ph1_Diode.ipynb new file mode 100644 index 0000000000..a857925926 --- /dev/null +++ b/examples/Notebooks/Circuits/EMT_Ph1_Diode.ipynb @@ -0,0 +1,125 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# EMT Ph3 Linear Circuit SSN" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run C++ examples" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import subprocess\n", + "\n", + "#%matplotlib widget\n", + "\n", + "name = 'EMT_Ph1_Diode_test'\n", + "\n", + "dpsim_path = subprocess.Popen(['git', 'rev-parse', '--show-toplevel'], stdout=subprocess.PIPE).communicate()[0].rstrip().decode('utf-8')\n", + "\n", + "path_exec = dpsim_path + '/build/dpsim/examples/cxx/'\n", + "sim = subprocess.Popen([path_exec + name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)\n", + "print(sim.communicate()[0].decode())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from villas.dataprocessing.readtools import *\n", + "from villas.dataprocessing.timeseries import *\n", + "from villas.dataprocessing.timeseries import TimeSeries as ts\n", + "import matplotlib.pyplot as plt\n", + "import re\n", + "import numpy as np\n", + "import math\n", + "\n", + "work_dir = os.getcwd() + \"/logs/\"\n", + "path_logfile = work_dir + name + '/' + name + '.csv'\n", + "ts_dpsim_EMT = read_timeseries_dpsim(path_logfile)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load Results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.close('all')\n", + "fig1 = plt.figure()\n", + "\n", + "plt.plot(ts_dpsim_EMT['V_Diode'].time, ts_dpsim_EMT['V_Diode'].values, \"r-\", label='V_D')\n", + "\n", + "plt.legend(loc = 4)\n", + "#plt.legend(bbox_to_anchor=(1,1))\n", + "\n", + "plt.title('Diode Voltage')\n", + "plt.xlabel('t [s]')\n", + "plt.ylabel('Voltage [V]')\n", + "\n", + "fig2 = plt.figure()\n", + "\n", + "plt.plot(ts_dpsim_EMT['I_Diode'].time, ts_dpsim_EMT['I_Diode'].values, \"r-\", label='I_D')\n", + "\n", + "plt.legend(loc = 4)\n", + "#plt.legend(bbox_to_anchor=(1,1))\n", + "\n", + "plt.title('Diode Current')\n", + "plt.xlabel('t [s]')\n", + "plt.ylabel('Current [A]')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + }, + "tests": { + "skip": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Notebooks/Circuits/EMT_Ph1_VS_R1_Diode.ipynb b/examples/Notebooks/Circuits/EMT_Ph1_VS_R1_Diode.ipynb new file mode 100644 index 0000000000..11b1eb6406 --- /dev/null +++ b/examples/Notebooks/Circuits/EMT_Ph1_VS_R1_Diode.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from villas.dataprocessing.readtools import *\n", + "from villas.dataprocessing.timeseries import *\n", + "from villas.dataprocessing.timeseries import TimeSeries as ts\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import dpsimpy\n", + "import re\n", + "import os\n", + "\n", + "%matplotlib widget\n", + "\n", + "#Define simulation scenario\n", + "time_step = 0.0001\n", + "final_time = 0.1 #0.006\n", + "simName = \"EMT_Ph1_VS_R1_Diode\"\n", + "\n", + "dpsimpy.Logger.set_log_dir('logs/' + simName)\n", + "\n", + "#Nodes\n", + "gnd = dpsimpy.emt.SimNode.gnd\n", + "n1 = dpsimpy.emt.SimNode(\"n1\", dpsimpy.PhaseType.Single)\n", + "n2 = dpsimpy.emt.SimNode(\"n2\", dpsimpy.PhaseType.Single)\n", + "\n", + "#Components\n", + "vs = dpsimpy.emt.ph1.VoltageSource(\"vs\")\n", + "vs.set_parameters(complex(1.,0.), 50.0);\n", + "\n", + "load = dpsimpy.emt.ph1.Resistor(\"r1\")\n", + "load.set_parameters(10.)\n", + "\n", + "diode = dpsimpy.emt.ph1.Diode(\"Diode\");\n", + "\n", + "#Topology\n", + "vs.connect([gnd, n1]);\n", + "load.connect([n2, n1]);\n", + "diode.connect([gnd, n2]);\n", + "\n", + "sys = dpsimpy.SystemTopology(50, [n1, n2], [vs, load, diode])\n", + "\n", + "#Logging\n", + "logger = dpsimpy.Logger(simName)\n", + "logger.log_attribute(\"I_Diode\", \"i_intf\", diode)\n", + "logger.log_attribute(\"V_Diode\", \"v_intf\", diode)\n", + "logger.log_attribute(\"V_Resistor\", \"v_intf\", load)\n", + "logger.log_attribute(\"V_VS\", \"v_intf\", vs)\n", + "\n", + "# Simulation\n", + "sim = dpsimpy.Simulation(simName)\n", + "sim.set_system(sys)\n", + "sim.set_time_step(time_step)\n", + "sim.set_final_time(final_time)\n", + "sim.set_domain(dpsimpy.Domain.EMT)\n", + "sim.set_solver(dpsimpy.Solver.ITERATIVEMNA)\n", + "sim.add_logger(logger)\n", + "sim.run()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "path_logfile = os.getcwd() + \"/logs/\" + simName + '/' + simName + '.csv'\n", + "ts_dpsim_EMT = read_timeseries_dpsim(path_logfile)\n", + "\n", + "plt.close('all')\n", + "fig1 = plt.figure()\n", + "\n", + "plt.plot(ts_dpsim_EMT['V_Diode'].time, ts_dpsim_EMT['V_Diode'].values, \"b-\", label='V_D')\n", + "plt.plot(ts_dpsim_EMT['V_Resistor'].time, ts_dpsim_EMT['V_Resistor'].values, \"g-\", label='V_R')\n", + "#plt.plot(ts_dpsim_EMT['V_VS'].time, ts_dpsim_EMT['V_VS'].values, \"r-\", label='V_VS')\n", + "\n", + "#difference = ts_dpsim_EMT['V_VS'].values - (ts_dpsim_EMT['V_Resistor'].values+ts_dpsim_EMT['V_Diode'].values)\n", + "#plt.plot(ts_dpsim_EMT['V_VS'].time, difference, \"b-\", label='difference')\n", + "\n", + "plt.legend(loc = 4)\n", + "#plt.legend(bbox_to_anchor=(1,1))\n", + "\n", + "plt.title('Voltages')\n", + "plt.xlabel('t [s]')\n", + "plt.ylabel('Voltage [V]')\n", + "\n", + "fig2 = plt.figure()\n", + "\n", + "plt.plot(ts_dpsim_EMT['I_Diode'].time, ts_dpsim_EMT['I_Diode'].values, \"r-\", label='I_D')\n", + "\n", + "plt.legend(loc = 4)\n", + "\n", + "plt.title('Diode Current')\n", + "plt.xlabel('t [s]')\n", + "plt.ylabel('Current [A]')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}