From c916059a30bd5d426ab1759075b4711200333622 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Fri, 26 Mar 2010 12:57:52 +0100 Subject: [PATCH 01/29] new engine: multithreaded --- FDTD/engine_multithread.cpp | 109 ++++++++++++++++++++++++++++++++++++ FDTD/engine_multithread.h | 45 +++++++++++++++ openEMS.pro | 6 +- openems.cpp | 17 +++++- openems.h | 3 + 5 files changed, 177 insertions(+), 3 deletions(-) create mode 100644 FDTD/engine_multithread.cpp create mode 100644 FDTD/engine_multithread.h diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp new file mode 100644 index 0000000..ee5e167 --- /dev/null +++ b/FDTD/engine_multithread.cpp @@ -0,0 +1,109 @@ +/* +* Copyright (C) 2010 Sebastian Held (sebastian.held@gmx.de) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#include "engine_multithread.h" +#include "tools/array_ops.h" + +Engine_Multithread::Engine_Multithread(Operator* op) : Engine(op) +{ +} + +Engine_Multithread::~Engine_Multithread() +{ +} + +void Engine_Multithread::Init() +{ + Engine::Init(); +} + +void Engine_Multithread::Reset() +{ + Engine::Reset(); +} + +bool Engine_Multithread::IterateTS(unsigned int iterTS) +{ + unsigned int pos[3]; + int exc_pos; + bool shift[3]; + + for (unsigned int iter=0;iternumLines[0];++pos[0]) + { + shift[0]=pos[0]; + for (pos[1]=0;pos[1]numLines[1];++pos[1]) + { + shift[1]=pos[1]; + for (pos[2]=0;pos[2]numLines[2];++pos[2]) + { + shift[2]=pos[2]; + //do the updates here + //for x + volt[0][pos[0]][pos[1]][pos[2]] *= Op->vv[0][pos[0]][pos[1]][pos[2]]; + volt[0][pos[0]][pos[1]][pos[2]] += Op->vi[0][pos[0]][pos[1]][pos[2]] * ( curr[2][pos[0]][pos[1]][pos[2]] - curr[2][pos[0]][pos[1]-shift[1]][pos[2]] - curr[1][pos[0]][pos[1]][pos[2]] + curr[1][pos[0]][pos[1]][pos[2]-shift[2]]); + + //for y + volt[1][pos[0]][pos[1]][pos[2]] *= Op->vv[1][pos[0]][pos[1]][pos[2]]; + volt[1][pos[0]][pos[1]][pos[2]] += Op->vi[1][pos[0]][pos[1]][pos[2]] * ( curr[0][pos[0]][pos[1]][pos[2]] - curr[0][pos[0]][pos[1]][pos[2]-shift[2]] - curr[2][pos[0]][pos[1]][pos[2]] + curr[2][pos[0]-shift[0]][pos[1]][pos[2]]); + + //for x + volt[2][pos[0]][pos[1]][pos[2]] *= Op->vv[2][pos[0]][pos[1]][pos[2]]; + volt[2][pos[0]][pos[1]][pos[2]] += Op->vi[2][pos[0]][pos[1]][pos[2]] * ( curr[1][pos[0]][pos[1]][pos[2]] - curr[1][pos[0]-shift[0]][pos[1]][pos[2]] - curr[0][pos[0]][pos[1]][pos[2]] + curr[0][pos[0]][pos[1]-shift[1]][pos[2]]); + } + } + } + + //soft voltage excitation here (E-field excite) + for (unsigned int n=0;nE_Exc_Count;++n) + { + exc_pos = (int)numTS - (int)Op->E_Exc_delay[n]; + exc_pos*= (exc_pos>0 && exc_pos<(int)Op->ExciteLength); +// if (n==0) cerr << numTS << " => " << Op->ExciteSignal[exc_pos] << endl; + volt[Op->E_Exc_dir[n]][Op->E_Exc_index[0][n]][Op->E_Exc_index[1][n]][Op->E_Exc_index[2][n]] += Op->E_Exc_amp[n]*Op->ExciteSignal[exc_pos]; + } + + //current updates + for (pos[0]=0;pos[0]numLines[0]-1;++pos[0]) + { + for (pos[1]=0;pos[1]numLines[1]-1;++pos[1]) + { + for (pos[2]=0;pos[2]numLines[2]-1;++pos[2]) + { + //do the updates here + //for x + curr[0][pos[0]][pos[1]][pos[2]] *= Op->ii[0][pos[0]][pos[1]][pos[2]]; + curr[0][pos[0]][pos[1]][pos[2]] += Op->iv[0][pos[0]][pos[1]][pos[2]] * ( volt[2][pos[0]][pos[1]][pos[2]] - volt[2][pos[0]][pos[1]+1][pos[2]] - volt[1][pos[0]][pos[1]][pos[2]] + volt[1][pos[0]][pos[1]][pos[2]+1]); + + //for y + curr[1][pos[0]][pos[1]][pos[2]] *= Op->ii[1][pos[0]][pos[1]][pos[2]]; + curr[1][pos[0]][pos[1]][pos[2]] += Op->iv[1][pos[0]][pos[1]][pos[2]] * ( volt[0][pos[0]][pos[1]][pos[2]] - volt[0][pos[0]][pos[1]][pos[2]+1] - volt[2][pos[0]][pos[1]][pos[2]] + volt[2][pos[0]+1][pos[1]][pos[2]]); + + //for x + curr[2][pos[0]][pos[1]][pos[2]] *= Op->ii[2][pos[0]][pos[1]][pos[2]]; + curr[2][pos[0]][pos[1]][pos[2]] += Op->iv[2][pos[0]][pos[1]][pos[2]] * ( volt[1][pos[0]][pos[1]][pos[2]] - volt[1][pos[0]+1][pos[1]][pos[2]] - volt[0][pos[0]][pos[1]][pos[2]] + volt[0][pos[0]][pos[1]+1][pos[2]]); + } + } + } + + //soft current excitation here (H-field excite) + ++numTS; + } + return true; +} diff --git a/FDTD/engine_multithread.h b/FDTD/engine_multithread.h new file mode 100644 index 0000000..3d45b6c --- /dev/null +++ b/FDTD/engine_multithread.h @@ -0,0 +1,45 @@ +/* +* Copyright (C) 2010 Sebastian Held (sebastian.held@gmx.de) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#ifndef ENGINE_MULTITHREAD_H +#define ENGINE_MULTITHREAD_H + +#include "operator.h" +#include "engine.h" + +class Engine_Multithread : public Engine +{ + friend class Processing; + friend class ProcessVoltage; + friend class ProcessCurrent; + friend class ProcessFields; + friend class ProcessFieldsTD; +public: + Engine_Multithread(Operator* op); + virtual ~Engine_Multithread(); + + virtual void Init(); + virtual void Reset(); + + //!Iterate a number of timesteps + virtual bool IterateTS(unsigned int iterTS); + + +protected: +}; + +#endif // ENGINE_MULTITHREAD_H diff --git a/openEMS.pro b/openEMS.pro index 43c0d75..0098bf2 100644 --- a/openEMS.pro +++ b/openEMS.pro @@ -31,7 +31,8 @@ SOURCES += main.cpp \ FDTD/processfields_td.cpp \ FDTD/processcurrent.cpp \ examples/FDTD_examples.cpp \ - openems.cpp + openems.cpp \ + FDTD/engine_multithread.cpp HEADERS += tools/ErrorMsg.h \ tools/AdrOp.h \ tools/constants.h \ @@ -44,4 +45,5 @@ HEADERS += tools/ErrorMsg.h \ FDTD/processfields_td.h \ FDTD/processcurrent.h \ examples/FDTD_examples.h \ - openems.h + openems.h \ + FDTD/engine_multithread.h diff --git a/openems.cpp b/openems.cpp index fe9790e..e2ffc2f 100644 --- a/openems.cpp +++ b/openems.cpp @@ -20,6 +20,7 @@ #include "tools/array_ops.h" #include "FDTD/operator.h" #include "FDTD/engine.h" +#include "FDTD/engine_multithread.h" #include "FDTD/processvoltage.h" #include "FDTD/processcurrent.h" #include "FDTD/processfields_td.h" @@ -95,6 +96,12 @@ bool openEMS::parseCommandLineArgument( const char *argv ) DebugOperator(); return true; } + else if (strcmp(argv,"--engine=multithreaded")==0) + { + cout << "openEMS - enabled multithreading" << endl; + m_engine = EngineType_Multithreaded; + return true; + } return false; } @@ -217,7 +224,15 @@ int openEMS::SetupFDTD(const char* file) cout << "Creation time for operator: " << difftime(OpDoneTime,startTime) << " s" << endl; //create FDTD engine - FDTD_Eng = new Engine(FDTD_Op); + switch (m_engine) { + case EngineType_Multithreaded: + FDTD_Eng = new Engine_Multithread(FDTD_Op); + break; + default: + FDTD_Eng = new Engine(FDTD_Op); + break; + } + time_t currTime = time(NULL); diff --git a/openems.h b/openems.h index 73bc943..ae2885d 100644 --- a/openems.h +++ b/openems.h @@ -52,6 +52,9 @@ protected: Operator* FDTD_Op; Engine* FDTD_Eng; ProcessingArray* PA; + + enum EngineType {EngineType_Standard,EngineType_Multithreaded}; + EngineType m_engine; }; #endif // OPENEMS_H From a5e4ab623327ebb443ed24b47e731063c550de6d Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Fri, 26 Mar 2010 15:52:09 +0100 Subject: [PATCH 02/29] change rpath linking flags --- openEMS.pro | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openEMS.pro b/openEMS.pro index 0098bf2..fd09752 100644 --- a/openEMS.pro +++ b/openEMS.pro @@ -15,10 +15,9 @@ LIBS += -L../CSXCAD \ -lfparser \ -L../tinyxml \ -ltinyxml -QMAKE_LFLAGS += \'-Wl,-rpath,\$$ORIGIN/../CSXCAD\' -QMAKE_LFLAGS += \'-Wl,-rpath,\$$ORIGIN/../fparser\' -QMAKE_LFLAGS += \'-Wl,-rpath,\$$ORIGIN/../tinyxml\' - +QMAKE_LFLAGS += '-Wl,-rpath,\$$ORIGIN/../CSXCAD' +QMAKE_LFLAGS += '-Wl,-rpath,\$$ORIGIN/../fparser' +QMAKE_LFLAGS += '-Wl,-rpath,\$$ORIGIN/../tinyxml' SOURCES += main.cpp \ tools/ErrorMsg.cpp \ tools/AdrOp.cpp \ From f46fd11416361dc5746e5600bc7ae6e0fa1a1c59 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Fri, 26 Mar 2010 17:14:37 +0100 Subject: [PATCH 03/29] explicitly set compiler options --- openEMS.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openEMS.pro b/openEMS.pro index fd09752..9f10406 100644 --- a/openEMS.pro +++ b/openEMS.pro @@ -46,3 +46,6 @@ HEADERS += tools/ErrorMsg.h \ examples/FDTD_examples.h \ openems.h \ FDTD/engine_multithread.h + +QMAKE_CXXFLAGS_RELEASE = -O2 -g -march=native +QMAKE_CXXFLAGS_DEBUG = -O0 -g -march=native From a7ccec254d9eda6b87ebac1b2717b3d8216d05e7 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Fri, 26 Mar 2010 17:24:43 +0100 Subject: [PATCH 04/29] static createEngine() added to work around virtual constructor problems --- FDTD/engine.cpp | 10 +++++++++- FDTD/engine.h | 3 ++- FDTD/engine_multithread.cpp | 9 +++++++++ FDTD/engine_multithread.h | 5 +++-- openems.cpp | 4 ++-- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/FDTD/engine.cpp b/FDTD/engine.cpp index 277234f..15dc55b 100644 --- a/FDTD/engine.cpp +++ b/FDTD/engine.cpp @@ -18,10 +18,18 @@ #include "engine.h" #include "tools/array_ops.h" +//! \brief construct an Engine instance +//! it's the responsibility of the caller to free the returned pointer +Engine* Engine::createEngine(Operator* op) +{ + Engine* e = new Engine(op); + e->Init(); + return e; +} + Engine::Engine(Operator* op) { Op = op; - Init(); } Engine::~Engine() diff --git a/FDTD/engine.h b/FDTD/engine.h index 401fa13..4e98ddd 100644 --- a/FDTD/engine.h +++ b/FDTD/engine.h @@ -28,7 +28,7 @@ class Engine friend class ProcessFields; friend class ProcessFieldsTD; public: - Engine(Operator* op); + static Engine* createEngine(Operator* op); virtual ~Engine(); virtual void Init(); @@ -40,6 +40,7 @@ public: unsigned int GetNumberOfTimesteps() {return numTS;}; protected: + Engine(Operator* op); Operator* Op; FDTD_FLOAT**** volt; diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp index ee5e167..c974835 100644 --- a/FDTD/engine_multithread.cpp +++ b/FDTD/engine_multithread.cpp @@ -18,6 +18,15 @@ #include "engine_multithread.h" #include "tools/array_ops.h" +//! \brief construct an Engine_Multithread instance +//! it's the responsibility of the caller to free the returned pointer +Engine_Multithread* Engine_Multithread::createEngine(Operator* op) +{ + Engine_Multithread* e = new Engine_Multithread(op); + e->Init(); + return e; +} + Engine_Multithread::Engine_Multithread(Operator* op) : Engine(op) { } diff --git a/FDTD/engine_multithread.h b/FDTD/engine_multithread.h index 3d45b6c..24f532e 100644 --- a/FDTD/engine_multithread.h +++ b/FDTD/engine_multithread.h @@ -29,8 +29,8 @@ class Engine_Multithread : public Engine friend class ProcessFields; friend class ProcessFieldsTD; public: - Engine_Multithread(Operator* op); - virtual ~Engine_Multithread(); + static Engine_Multithread* createEngine(Operator* op); + virtual ~Engine_Multithread(); virtual void Init(); virtual void Reset(); @@ -40,6 +40,7 @@ public: protected: + Engine_Multithread(Operator* op); }; #endif // ENGINE_MULTITHREAD_H diff --git a/openems.cpp b/openems.cpp index e2ffc2f..d920e70 100644 --- a/openems.cpp +++ b/openems.cpp @@ -226,10 +226,10 @@ int openEMS::SetupFDTD(const char* file) //create FDTD engine switch (m_engine) { case EngineType_Multithreaded: - FDTD_Eng = new Engine_Multithread(FDTD_Op); + FDTD_Eng = Engine_Multithread::createEngine(FDTD_Op); break; default: - FDTD_Eng = new Engine(FDTD_Op); + FDTD_Eng = Engine::createEngine(FDTD_Op); break; } From cdc6510969f0f0ca4a69dd5d0986c66a877c84e8 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Fri, 26 Mar 2010 17:34:47 +0100 Subject: [PATCH 05/29] fix rpath again (only usable from _within_ qtcreator ; remove qt libs --- openEMS.pro | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openEMS.pro b/openEMS.pro index 9f10406..4cb933e 100644 --- a/openEMS.pro +++ b/openEMS.pro @@ -1,7 +1,7 @@ # ------------------------------------------------- # Project created by QtCreator 2010-02-26T22:34:51 # ------------------------------------------------- -QT -= gui +QT -= gui core TARGET = openEMS CONFIG += console CONFIG -= app_bundle @@ -15,9 +15,9 @@ LIBS += -L../CSXCAD \ -lfparser \ -L../tinyxml \ -ltinyxml -QMAKE_LFLAGS += '-Wl,-rpath,\$$ORIGIN/../CSXCAD' -QMAKE_LFLAGS += '-Wl,-rpath,\$$ORIGIN/../fparser' -QMAKE_LFLAGS += '-Wl,-rpath,\$$ORIGIN/../tinyxml' +QMAKE_LFLAGS += \'-Wl,-rpath,\$$ORIGIN/../CSXCAD\' +QMAKE_LFLAGS += \'-Wl,-rpath,\$$ORIGIN/../fparser\' +QMAKE_LFLAGS += \'-Wl,-rpath,\$$ORIGIN/../tinyxml\' SOURCES += main.cpp \ tools/ErrorMsg.cpp \ tools/AdrOp.cpp \ From 79b0e6a2e0dc7113269b2c3486e3d3b41d9cfd44 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Fri, 26 Mar 2010 23:53:05 +0100 Subject: [PATCH 06/29] first implementation of a multithreaded engine (bugs and mem leaks present!) --- FDTD/engine_multithread.cpp | 187 +++++++++++++++++++++++++++--------- FDTD/engine_multithread.h | 39 ++++++++ openEMS.pro | 3 +- 3 files changed, 180 insertions(+), 49 deletions(-) diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp index c974835..649a205 100644 --- a/FDTD/engine_multithread.cpp +++ b/FDTD/engine_multithread.cpp @@ -38,81 +38,172 @@ Engine_Multithread::~Engine_Multithread() void Engine_Multithread::Init() { Engine::Init(); + + numTS = 0; + + // initialize threads + int numThreads = boost::thread::hardware_concurrency(); + std::cout << "using " << numThreads << " threads" << std::endl; + m_barrier1 = new boost::barrier(numThreads+1); // numThread workers + 1 excitation thread + m_barrier2 = new boost::barrier(numThreads+1); // numThread workers + 1 excitation thread + m_barrier3 = new boost::barrier(numThreads); // numThread workers + m_startBarrier = new boost::barrier(numThreads+1); // numThread workers + 1 controller + m_stopBarrier = new boost::barrier(numThreads+1); // numThread workers + 1 controller + + for (int n=0; nnumLines[0]+numThreads-1) / numThreads; + unsigned int start = n * linesPerThread; + unsigned int stop = min( (n+1) * linesPerThread - 1, Op->numLines[0]-1 ); + //std::cout << "### " << Op->numLines[0] << " " << linesPerThread << " " << start << " " << stop << std::endl; + boost::thread *t = new boost::thread( thread(this,start,stop) ); + m_thread_group.add_thread( t ); + } + boost::thread *t = new boost::thread( thread_e_excitation(this) ); + m_thread_group.add_thread( t ); } void Engine_Multithread::Reset() { + + Engine::Reset(); } bool Engine_Multithread::IterateTS(unsigned int iterTS) { + m_iterTS = iterTS; + //cout << "bool Engine_Multithread::IterateTS(): starting threads ..."; + m_startBarrier->wait(); // start the threads + //cout << "... threads started"; + + m_stopBarrier->wait(); // wait for the threads to finish time steps + return true; +} + + + + + + + +thread::thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop ) : m_enginePtr(ptr), m_start(start), m_stop(stop), m_stopThread(false) +{ + Op = m_enginePtr->Op; + volt = m_enginePtr->volt; + curr = m_enginePtr->curr; +} + +void thread::operator()() +{ + //std::cout << "thread::operator() Parameters: " << m_start << " " << m_stop << std::endl; + unsigned int pos[3]; - int exc_pos; bool shift[3]; - for (unsigned int iter=0;iternumLines[0];++pos[0]) + while (!m_stopThread) { + // wait for start + //cout << "Thread " << boost::this_thread::get_id() << " waiting..." << endl; + m_enginePtr->m_startBarrier->wait(); + //cout << "Thread " << boost::this_thread::get_id() << " waiting... started." << endl; + + for (unsigned int iter=0;iterm_iterTS;++iter) { - shift[0]=pos[0]; - for (pos[1]=0;pos[1]numLines[1];++pos[1]) + //voltage updates + for (pos[0]=m_start;pos[0]<=m_stop;++pos[0]) { - shift[1]=pos[1]; - for (pos[2]=0;pos[2]numLines[2];++pos[2]) + shift[0]=pos[0]; + for (pos[1]=0;pos[1]numLines[1];++pos[1]) { - shift[2]=pos[2]; - //do the updates here - //for x - volt[0][pos[0]][pos[1]][pos[2]] *= Op->vv[0][pos[0]][pos[1]][pos[2]]; - volt[0][pos[0]][pos[1]][pos[2]] += Op->vi[0][pos[0]][pos[1]][pos[2]] * ( curr[2][pos[0]][pos[1]][pos[2]] - curr[2][pos[0]][pos[1]-shift[1]][pos[2]] - curr[1][pos[0]][pos[1]][pos[2]] + curr[1][pos[0]][pos[1]][pos[2]-shift[2]]); + shift[1]=pos[1]; + for (pos[2]=0;pos[2]numLines[2];++pos[2]) + { + shift[2]=pos[2]; + //do the updates here + //for x + volt[0][pos[0]][pos[1]][pos[2]] *= Op->vv[0][pos[0]][pos[1]][pos[2]]; + volt[0][pos[0]][pos[1]][pos[2]] += Op->vi[0][pos[0]][pos[1]][pos[2]] * ( curr[2][pos[0]][pos[1]][pos[2]] - curr[2][pos[0]][pos[1]-shift[1]][pos[2]] - curr[1][pos[0]][pos[1]][pos[2]] + curr[1][pos[0]][pos[1]][pos[2]-shift[2]]); - //for y - volt[1][pos[0]][pos[1]][pos[2]] *= Op->vv[1][pos[0]][pos[1]][pos[2]]; - volt[1][pos[0]][pos[1]][pos[2]] += Op->vi[1][pos[0]][pos[1]][pos[2]] * ( curr[0][pos[0]][pos[1]][pos[2]] - curr[0][pos[0]][pos[1]][pos[2]-shift[2]] - curr[2][pos[0]][pos[1]][pos[2]] + curr[2][pos[0]-shift[0]][pos[1]][pos[2]]); + //for y + volt[1][pos[0]][pos[1]][pos[2]] *= Op->vv[1][pos[0]][pos[1]][pos[2]]; + volt[1][pos[0]][pos[1]][pos[2]] += Op->vi[1][pos[0]][pos[1]][pos[2]] * ( curr[0][pos[0]][pos[1]][pos[2]] - curr[0][pos[0]][pos[1]][pos[2]-shift[2]] - curr[2][pos[0]][pos[1]][pos[2]] + curr[2][pos[0]-shift[0]][pos[1]][pos[2]]); - //for x - volt[2][pos[0]][pos[1]][pos[2]] *= Op->vv[2][pos[0]][pos[1]][pos[2]]; - volt[2][pos[0]][pos[1]][pos[2]] += Op->vi[2][pos[0]][pos[1]][pos[2]] * ( curr[1][pos[0]][pos[1]][pos[2]] - curr[1][pos[0]-shift[0]][pos[1]][pos[2]] - curr[0][pos[0]][pos[1]][pos[2]] + curr[0][pos[0]][pos[1]-shift[1]][pos[2]]); + //for x + volt[2][pos[0]][pos[1]][pos[2]] *= Op->vv[2][pos[0]][pos[1]][pos[2]]; + volt[2][pos[0]][pos[1]][pos[2]] += Op->vi[2][pos[0]][pos[1]][pos[2]] * ( curr[1][pos[0]][pos[1]][pos[2]] - curr[1][pos[0]-shift[0]][pos[1]][pos[2]] - curr[0][pos[0]][pos[1]][pos[2]] + curr[0][pos[0]][pos[1]-shift[1]][pos[2]]); + } } } + + //cout << "Thread " << boost::this_thread::get_id() << " m_barrier1 waiting..." << endl; + m_enginePtr->m_barrier1->wait(); + + // e-field excitation (thread thread_e_excitation) + + m_enginePtr->m_barrier2->wait(); + // e_excitation finished + + //current updates + for (pos[0]=m_start;pos[0]<=m_stop-1;++pos[0]) + { + for (pos[1]=0;pos[1]numLines[1]-1;++pos[1]) + { + for (pos[2]=0;pos[2]numLines[2]-1;++pos[2]) + { + //do the updates here + //for x + curr[0][pos[0]][pos[1]][pos[2]] *= Op->ii[0][pos[0]][pos[1]][pos[2]]; + curr[0][pos[0]][pos[1]][pos[2]] += Op->iv[0][pos[0]][pos[1]][pos[2]] * ( volt[2][pos[0]][pos[1]][pos[2]] - volt[2][pos[0]][pos[1]+1][pos[2]] - volt[1][pos[0]][pos[1]][pos[2]] + volt[1][pos[0]][pos[1]][pos[2]+1]); + + //for y + curr[1][pos[0]][pos[1]][pos[2]] *= Op->ii[1][pos[0]][pos[1]][pos[2]]; + curr[1][pos[0]][pos[1]][pos[2]] += Op->iv[1][pos[0]][pos[1]][pos[2]] * ( volt[0][pos[0]][pos[1]][pos[2]] - volt[0][pos[0]][pos[1]][pos[2]+1] - volt[2][pos[0]][pos[1]][pos[2]] + volt[2][pos[0]+1][pos[1]][pos[2]]); + + //for x + curr[2][pos[0]][pos[1]][pos[2]] *= Op->ii[2][pos[0]][pos[1]][pos[2]]; + curr[2][pos[0]][pos[1]][pos[2]] += Op->iv[2][pos[0]][pos[1]][pos[2]] * ( volt[1][pos[0]][pos[1]][pos[2]] - volt[1][pos[0]+1][pos[1]][pos[2]] - volt[0][pos[0]][pos[1]][pos[2]] + volt[0][pos[0]][pos[1]+1][pos[2]]); + } + } + } + + m_enginePtr->m_barrier3->wait(); + + //soft current excitation here (H-field excite) + + ++m_enginePtr->numTS; // FIXME BUG!!!!! increases not by 1, but by the number of threads!!!! } + m_enginePtr->m_stopBarrier->wait(); + } +} + + +thread_e_excitation::thread_e_excitation( Engine_Multithread* ptr ) : m_enginePtr(ptr), m_stopThread(false) +{ + Op = m_enginePtr->Op; + volt = m_enginePtr->volt; + curr = m_enginePtr->curr; +} + +void thread_e_excitation::operator()() +{ + //std::cout << "thread_e_excitation::operator()" << std::endl; + + while (!m_stopThread) { + + // waiting on thread + m_enginePtr->m_barrier1->wait(); + + int exc_pos; //soft voltage excitation here (E-field excite) for (unsigned int n=0;nE_Exc_Count;++n) { - exc_pos = (int)numTS - (int)Op->E_Exc_delay[n]; + exc_pos = (int)m_enginePtr->m_numTS - (int)Op->E_Exc_delay[n]; exc_pos*= (exc_pos>0 && exc_pos<(int)Op->ExciteLength); -// if (n==0) cerr << numTS << " => " << Op->ExciteSignal[exc_pos] << endl; + // if (n==0) cerr << numTS << " => " << Op->ExciteSignal[exc_pos] << endl; volt[Op->E_Exc_dir[n]][Op->E_Exc_index[0][n]][Op->E_Exc_index[1][n]][Op->E_Exc_index[2][n]] += Op->E_Exc_amp[n]*Op->ExciteSignal[exc_pos]; } - //current updates - for (pos[0]=0;pos[0]numLines[0]-1;++pos[0]) - { - for (pos[1]=0;pos[1]numLines[1]-1;++pos[1]) - { - for (pos[2]=0;pos[2]numLines[2]-1;++pos[2]) - { - //do the updates here - //for x - curr[0][pos[0]][pos[1]][pos[2]] *= Op->ii[0][pos[0]][pos[1]][pos[2]]; - curr[0][pos[0]][pos[1]][pos[2]] += Op->iv[0][pos[0]][pos[1]][pos[2]] * ( volt[2][pos[0]][pos[1]][pos[2]] - volt[2][pos[0]][pos[1]+1][pos[2]] - volt[1][pos[0]][pos[1]][pos[2]] + volt[1][pos[0]][pos[1]][pos[2]+1]); - - //for y - curr[1][pos[0]][pos[1]][pos[2]] *= Op->ii[1][pos[0]][pos[1]][pos[2]]; - curr[1][pos[0]][pos[1]][pos[2]] += Op->iv[1][pos[0]][pos[1]][pos[2]] * ( volt[0][pos[0]][pos[1]][pos[2]] - volt[0][pos[0]][pos[1]][pos[2]+1] - volt[2][pos[0]][pos[1]][pos[2]] + volt[2][pos[0]+1][pos[1]][pos[2]]); - - //for x - curr[2][pos[0]][pos[1]][pos[2]] *= Op->ii[2][pos[0]][pos[1]][pos[2]]; - curr[2][pos[0]][pos[1]][pos[2]] += Op->iv[2][pos[0]][pos[1]][pos[2]] * ( volt[1][pos[0]][pos[1]][pos[2]] - volt[1][pos[0]+1][pos[1]][pos[2]] - volt[0][pos[0]][pos[1]][pos[2]] + volt[0][pos[0]][pos[1]+1][pos[2]]); - } - } - } - - //soft current excitation here (H-field excite) - ++numTS; + // continueing thread + m_enginePtr->m_barrier2->wait(); } - return true; } diff --git a/FDTD/engine_multithread.h b/FDTD/engine_multithread.h index 24f532e..c3dead4 100644 --- a/FDTD/engine_multithread.h +++ b/FDTD/engine_multithread.h @@ -21,6 +21,8 @@ #include "operator.h" #include "engine.h" +#include + class Engine_Multithread : public Engine { friend class Processing; @@ -28,6 +30,8 @@ class Engine_Multithread : public Engine friend class ProcessCurrent; friend class ProcessFields; friend class ProcessFieldsTD; + friend class thread; + friend class thread_e_excitation; public: static Engine_Multithread* createEngine(Operator* op); virtual ~Engine_Multithread(); @@ -38,9 +42,44 @@ public: //!Iterate a number of timesteps virtual bool IterateTS(unsigned int iterTS); + void doWork(unsigned int start, unsigned int stop, unsigned int iterTS); + void doWork_e_excitation(unsigned int start, unsigned int stop, unsigned int iterTS); + protected: Engine_Multithread(Operator* op); + boost::thread_group m_thread_group; + boost::barrier *m_barrier1, *m_barrier2, *m_barrier3, *m_startBarrier, *m_stopBarrier; + volatile unsigned int m_iterTS; + volatile unsigned int m_numTS; +}; + + +class thread { +public: + thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop ); + void operator()(); + +protected: + unsigned int m_start, m_stop; + volatile bool m_stopThread; + Engine_Multithread *m_enginePtr; + Operator *Op; + FDTD_FLOAT**** volt; + FDTD_FLOAT**** curr; +}; + +class thread_e_excitation { +public: + thread_e_excitation( Engine_Multithread* ptr); + void operator()(); + +protected: + volatile bool m_stopThread; + Engine_Multithread *m_enginePtr; + Operator *Op; + FDTD_FLOAT**** volt; + FDTD_FLOAT**** curr; }; #endif // ENGINE_MULTITHREAD_H diff --git a/openEMS.pro b/openEMS.pro index 4cb933e..34c098e 100644 --- a/openEMS.pro +++ b/openEMS.pro @@ -14,7 +14,8 @@ LIBS += -L../CSXCAD \ -L../fparser \ -lfparser \ -L../tinyxml \ - -ltinyxml + -ltinyxml \ + -lboost_thread QMAKE_LFLAGS += \'-Wl,-rpath,\$$ORIGIN/../CSXCAD\' QMAKE_LFLAGS += \'-Wl,-rpath,\$$ORIGIN/../fparser\' QMAKE_LFLAGS += \'-Wl,-rpath,\$$ORIGIN/../tinyxml\' From d01900a48fcb255c161e00161bbb738ee32dd43b Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Sat, 27 Mar 2010 11:29:58 +0100 Subject: [PATCH 07/29] make it virtual --- FDTD/engine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FDTD/engine.h b/FDTD/engine.h index 4e98ddd..23c2d24 100644 --- a/FDTD/engine.h +++ b/FDTD/engine.h @@ -37,7 +37,7 @@ public: //!Iterate a number of timesteps virtual bool IterateTS(unsigned int iterTS); - unsigned int GetNumberOfTimesteps() {return numTS;}; + virtual unsigned int GetNumberOfTimesteps() {return numTS;}; protected: Engine(Operator* op); From e108e17cec573d20d8cc1c29a00ad5b1711ba1ed Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Sat, 27 Mar 2010 11:32:06 +0100 Subject: [PATCH 08/29] bugfix: calculate correct number of timesteps --- FDTD/engine_multithread.cpp | 24 +++++++++++++----------- FDTD/engine_multithread.h | 7 +++---- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp index 649a205..6f3fa67 100644 --- a/FDTD/engine_multithread.cpp +++ b/FDTD/engine_multithread.cpp @@ -42,16 +42,16 @@ void Engine_Multithread::Init() numTS = 0; // initialize threads - int numThreads = boost::thread::hardware_concurrency(); - std::cout << "using " << numThreads << " threads" << std::endl; - m_barrier1 = new boost::barrier(numThreads+1); // numThread workers + 1 excitation thread - m_barrier2 = new boost::barrier(numThreads+1); // numThread workers + 1 excitation thread - m_barrier3 = new boost::barrier(numThreads); // numThread workers - m_startBarrier = new boost::barrier(numThreads+1); // numThread workers + 1 controller - m_stopBarrier = new boost::barrier(numThreads+1); // numThread workers + 1 controller + m_numThreads = boost::thread::hardware_concurrency(); + std::cout << "using " << m_numThreads << " threads" << std::endl; + m_barrier1 = new boost::barrier(m_numThreads+1); // numThread workers + 1 excitation thread + m_barrier2 = new boost::barrier(m_numThreads+1); // numThread workers + 1 excitation thread + m_barrier3 = new boost::barrier(m_numThreads); // numThread workers + m_startBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller + m_stopBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller - for (int n=0; nnumLines[0]+numThreads-1) / numThreads; + for (int n=0; nnumLines[0]+m_numThreads-1) / m_numThreads; unsigned int start = n * linesPerThread; unsigned int stop = min( (n+1) * linesPerThread - 1, Op->numLines[0]-1 ); //std::cout << "### " << Op->numLines[0] << " " << linesPerThread << " " << start << " " << stop << std::endl; @@ -169,7 +169,7 @@ void thread::operator()() //soft current excitation here (H-field excite) - ++m_enginePtr->numTS; // FIXME BUG!!!!! increases not by 1, but by the number of threads!!!! + ++m_enginePtr->m_numTS_times_threads; } m_enginePtr->m_stopBarrier->wait(); @@ -194,10 +194,12 @@ void thread_e_excitation::operator()() m_enginePtr->m_barrier1->wait(); int exc_pos; + unsigned int numTS = m_enginePtr->m_numTS_times_threads / m_enginePtr->m_numThreads; + //soft voltage excitation here (E-field excite) for (unsigned int n=0;nE_Exc_Count;++n) { - exc_pos = (int)m_enginePtr->m_numTS - (int)Op->E_Exc_delay[n]; + exc_pos = (int)numTS - (int)Op->E_Exc_delay[n]; exc_pos*= (exc_pos>0 && exc_pos<(int)Op->ExciteLength); // if (n==0) cerr << numTS << " => " << Op->ExciteSignal[exc_pos] << endl; volt[Op->E_Exc_dir[n]][Op->E_Exc_index[0][n]][Op->E_Exc_index[1][n]][Op->E_Exc_index[2][n]] += Op->E_Exc_amp[n]*Op->ExciteSignal[exc_pos]; diff --git a/FDTD/engine_multithread.h b/FDTD/engine_multithread.h index c3dead4..7aec99e 100644 --- a/FDTD/engine_multithread.h +++ b/FDTD/engine_multithread.h @@ -42,16 +42,15 @@ public: //!Iterate a number of timesteps virtual bool IterateTS(unsigned int iterTS); - void doWork(unsigned int start, unsigned int stop, unsigned int iterTS); - void doWork_e_excitation(unsigned int start, unsigned int stop, unsigned int iterTS); - + virtual unsigned int GetNumberOfTimesteps() {return m_numTS_times_threads / m_numThreads;} protected: Engine_Multithread(Operator* op); boost::thread_group m_thread_group; boost::barrier *m_barrier1, *m_barrier2, *m_barrier3, *m_startBarrier, *m_stopBarrier; volatile unsigned int m_iterTS; - volatile unsigned int m_numTS; + volatile unsigned int m_numTS_times_threads; //!< numTS times the number of worker threads + unsigned int m_numThreads; //!< number of worker threads }; From 54344b1b86d5a0405d6cb3d11c9ceae17d93d9f8 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Sat, 27 Mar 2010 15:26:20 +0100 Subject: [PATCH 09/29] bug: field dumper directly access protected numTS member variable... --- FDTD/engine_multithread.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp index 6f3fa67..d180c66 100644 --- a/FDTD/engine_multithread.cpp +++ b/FDTD/engine_multithread.cpp @@ -40,6 +40,7 @@ void Engine_Multithread::Init() Engine::Init(); numTS = 0; + m_numTS_times_threads = 0; // initialize threads m_numThreads = boost::thread::hardware_concurrency(); @@ -77,6 +78,7 @@ bool Engine_Multithread::IterateTS(unsigned int iterTS) //cout << "... threads started"; m_stopBarrier->wait(); // wait for the threads to finish time steps + numTS = m_numTS_times_threads; return true; } From c9cc0cf2dc1a4c5b91eaccb292512bb475513fa6 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Sat, 27 Mar 2010 15:54:44 +0100 Subject: [PATCH 10/29] simplified time calculation --- openems.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/openems.cpp b/openems.cpp index d920e70..921ae40 100644 --- a/openems.cpp +++ b/openems.cpp @@ -33,8 +33,8 @@ double CalcDiffTime(timeval t1, timeval t2) { - double s_diff = difftime(t1.tv_sec,t2.tv_sec); - s_diff += ((double)t1.tv_usec-(double)t2.tv_usec)*1e-6; + double s_diff = t1.tv_sec - t2.tv_sec; + s_diff += (t1.tv_usec-t2.tv_usec)*1e-6; return s_diff; } @@ -315,17 +315,20 @@ void openEMS::RunFDTD() { cout << "Running FDTD engine... this may take a while... grab a coup of coffee?!?" << endl; - timeval currTime; - gettimeofday(&currTime,NULL); - timeval startTime = currTime; - timeval prevTime= currTime; ProcessFields ProcField(FDTD_Op,FDTD_Eng); double maxE=0,currE=0; double change=1; int prevTS=0,currTS=0; - double speed = (double)FDTD_Op->GetNumberCells()/1e6; + double speed = FDTD_Op->GetNumberCells()/1e6; double t_diff; + + timeval currTime; + gettimeofday(&currTime,NULL); + timeval startTime = currTime; + timeval prevTime= currTime; + //*************** simulate ************// + int step=PA->Process(); if ((step<0) || (step>NrTS)) step=NrTS; while ((FDTD_Eng->GetNumberOfTimesteps()endCrit)) @@ -345,7 +348,7 @@ void openEMS::RunFDTD() if (currE>maxE) maxE=currE; cout << "[@" << setw(8) << (int)CalcDiffTime(currTime,startTime) << "s] Timestep: " << setw(12) << currTS << " (" << setw(6) << setprecision(2) << std::fixed << (double)currTS/(double)NrTS*100.0 << "%)" ; - cout << " with currently " << setw(6) << setprecision(1) << std::fixed << speed*(double)(currTS-prevTS)/t_diff << " MCells/s" ; + cout << " with currently " << setw(6) << setprecision(1) << std::fixed << speed*(currTS-prevTS)/t_diff << " MCells/s" ; if (maxE) change = currE/maxE; cout << " --- Energy: ~" << setw(6) << setprecision(2) << std::scientific << currE << " (decrement: " << setw(6) << setprecision(2) << std::fixed << fabs(10.0*log10(change)) << "dB)" << endl; From fb193ac25ba209a1a9f4af66cd2e5c39b14d9d97 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Sat, 27 Mar 2010 22:57:25 +0100 Subject: [PATCH 11/29] debugging --- FDTD/engine_multithread.cpp | 39 ++++++++++++++++++++++++++++++++++++- FDTD/engine_multithread.h | 16 +++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp index d180c66..298ff77 100644 --- a/FDTD/engine_multithread.cpp +++ b/FDTD/engine_multithread.cpp @@ -18,6 +18,11 @@ #include "engine_multithread.h" #include "tools/array_ops.h" +#include "boost/date_time/posix_time/posix_time.hpp" +#include "boost/date_time/gregorian/gregorian.hpp" +#include + + //! \brief construct an Engine_Multithread instance //! it's the responsibility of the caller to free the returned pointer Engine_Multithread* Engine_Multithread::createEngine(Operator* op) @@ -33,6 +38,22 @@ Engine_Multithread::Engine_Multithread(Operator* op) : Engine(op) Engine_Multithread::~Engine_Multithread() { + //DEBUG + cout << "Engine_Multithread::~Engine_Multithread()" << endl; + std::map >::iterator it; + for (it=m_timer_list.begin(); it!=m_timer_list.end(); it++) { + std::cout << "*** DEBUG Thread: " << it->first << std::endl; + std::vector::iterator it2; + for (it2=it->second.begin(); it2second.end();) { + std::cout << "after voltage update, before barrier1: " << fixed << setprecision(6) << *(it2++) << std::endl; + std::cout << "after barrier1, before barrier2: " << fixed << setprecision(6) << *(it2++) << std::endl; + std::cout << "after barrier2, before current update: " << fixed << setprecision(6) << *(it2++) << std::endl; + std::cout << "after current update, before barrier3: " << fixed << setprecision(6) << *(it2++) << std::endl; + std::cout << "after barrier3: " << fixed << setprecision(6) << *(it2++) << std::endl; + } + } + //DEBUG + } void Engine_Multithread::Init() @@ -66,7 +87,6 @@ void Engine_Multithread::Init() void Engine_Multithread::Reset() { - Engine::Reset(); } @@ -108,6 +128,8 @@ void thread::operator()() m_enginePtr->m_startBarrier->wait(); //cout << "Thread " << boost::this_thread::get_id() << " waiting... started." << endl; + Timer timer1; + for (unsigned int iter=0;iterm_iterTS;++iter) { //voltage updates @@ -136,14 +158,23 @@ void thread::operator()() } } + // record time + m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); + //cout << "Thread " << boost::this_thread::get_id() << " m_barrier1 waiting..." << endl; m_enginePtr->m_barrier1->wait(); + // record time + m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); + // e-field excitation (thread thread_e_excitation) m_enginePtr->m_barrier2->wait(); // e_excitation finished + // record time + m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); + //current updates for (pos[0]=m_start;pos[0]<=m_stop-1;++pos[0]) { @@ -167,8 +198,14 @@ void thread::operator()() } } + // record time + m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); + m_enginePtr->m_barrier3->wait(); + // record time + m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); + //soft current excitation here (H-field excite) ++m_enginePtr->m_numTS_times_threads; diff --git a/FDTD/engine_multithread.h b/FDTD/engine_multithread.h index 7aec99e..65f9959 100644 --- a/FDTD/engine_multithread.h +++ b/FDTD/engine_multithread.h @@ -22,6 +22,18 @@ #include "engine.h" #include +#include +#include +#include + +//debug +class Timer { +public: + Timer() {gettimeofday(&t1,NULL);} + double elapsed() {gettimeofday(&t2,NULL); return (t2.tv_sec-t1.tv_sec) + (t2.tv_usec-t1.tv_usec)*1e-6;} +protected: + timeval t1,t2; +}; class Engine_Multithread : public Engine { @@ -51,9 +63,13 @@ protected: volatile unsigned int m_iterTS; volatile unsigned int m_numTS_times_threads; //!< numTS times the number of worker threads unsigned int m_numThreads; //!< number of worker threads + + //debug + std::map > m_timer_list; }; + class thread { public: thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop ); From b8180287e9b7655e9c911712b13b955c3d391e16 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Sun, 28 Mar 2010 13:10:16 +0200 Subject: [PATCH 12/29] time debug code can now be disabled --- FDTD/engine_multithread.cpp | 28 +++++++++++++++++++--------- FDTD/engine_multithread.h | 3 ++- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp index 298ff77..e51cf25 100644 --- a/FDTD/engine_multithread.cpp +++ b/FDTD/engine_multithread.cpp @@ -15,6 +15,16 @@ * along with this program. If not, see . */ +//#define ENABLE_DEBUG_TIME + +#ifdef ENABLE_DEBUG_TIME + #define DEBUG_TIME(x) x; +#else + #define DEBUG_TIME(x) ; +#endif + + + #include "engine_multithread.h" #include "tools/array_ops.h" @@ -38,7 +48,7 @@ Engine_Multithread::Engine_Multithread(Operator* op) : Engine(op) Engine_Multithread::~Engine_Multithread() { - //DEBUG +#ifdef ENABLE_DEBUG_TIME cout << "Engine_Multithread::~Engine_Multithread()" << endl; std::map >::iterator it; for (it=m_timer_list.begin(); it!=m_timer_list.end(); it++) { @@ -52,7 +62,7 @@ Engine_Multithread::~Engine_Multithread() std::cout << "after barrier3: " << fixed << setprecision(6) << *(it2++) << std::endl; } } - //DEBUG +#endif } @@ -98,7 +108,7 @@ bool Engine_Multithread::IterateTS(unsigned int iterTS) //cout << "... threads started"; m_stopBarrier->wait(); // wait for the threads to finish time steps - numTS = m_numTS_times_threads; + numTS = m_numTS_times_threads / m_numThreads; return true; } @@ -128,7 +138,7 @@ void thread::operator()() m_enginePtr->m_startBarrier->wait(); //cout << "Thread " << boost::this_thread::get_id() << " waiting... started." << endl; - Timer timer1; + DEBUG_TIME( Timer timer1 ); for (unsigned int iter=0;iterm_iterTS;++iter) { @@ -159,13 +169,13 @@ void thread::operator()() } // record time - m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); + DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) //cout << "Thread " << boost::this_thread::get_id() << " m_barrier1 waiting..." << endl; m_enginePtr->m_barrier1->wait(); // record time - m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); + DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) // e-field excitation (thread thread_e_excitation) @@ -173,7 +183,7 @@ void thread::operator()() // e_excitation finished // record time - m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); + DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) //current updates for (pos[0]=m_start;pos[0]<=m_stop-1;++pos[0]) @@ -199,12 +209,12 @@ void thread::operator()() } // record time - m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); + DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) m_enginePtr->m_barrier3->wait(); // record time - m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); + DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) //soft current excitation here (H-field excite) diff --git a/FDTD/engine_multithread.h b/FDTD/engine_multithread.h index 65f9959..e6abbb4 100644 --- a/FDTD/engine_multithread.h +++ b/FDTD/engine_multithread.h @@ -64,8 +64,9 @@ protected: volatile unsigned int m_numTS_times_threads; //!< numTS times the number of worker threads unsigned int m_numThreads; //!< number of worker threads - //debug +#ifdef ENABLE_DEBUG_TIME std::map > m_timer_list; +#endif }; From 4b12054f66345abc40796dfbacfa65ef93f07c39 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Tue, 30 Mar 2010 13:10:23 +0200 Subject: [PATCH 13/29] merged --- FDTD/operator.cpp | 14 ++++++++++++++ FDTD/operator.h | 1 + 2 files changed, 15 insertions(+) diff --git a/FDTD/operator.cpp b/FDTD/operator.cpp index a3fb64a..4cd1484 100644 --- a/FDTD/operator.cpp +++ b/FDTD/operator.cpp @@ -248,6 +248,20 @@ unsigned int Operator::CalcGaussianPulsExcitation(double f0, double fc) return GetNyquistNum(f0+fc); } +unsigned int Operator::CalcDiracPulsExcitation() +{ + if (dT==0) return 0; + + ExciteLength = 1; + cerr << "Operator::CalcDiracPulsExcitation: Length of the excite signal: " << ExciteLength << " timesteps" << endl; + delete[] ExciteSignal; + ExciteSignal = new FDTD_FLOAT[ExciteLength+1]; + ExciteSignal[0]=0.0; + ExciteSignal[1]=1.0; + + return 1; +} + unsigned int Operator::CalcSinusExcitation(double f0, int nTS) { if (dT==0) return 0; diff --git a/FDTD/operator.h b/FDTD/operator.h index 12ed41a..f17197c 100644 --- a/FDTD/operator.h +++ b/FDTD/operator.h @@ -41,6 +41,7 @@ public: virtual unsigned int CalcGaussianPulsExcitation(double f0, double fc); //! Calculate a sinusoidal excitation with frequency f0 and a duration of nTS number of timesteps \return number of Nyquist timesteps virtual unsigned int CalcSinusExcitation(double f0, int nTS); + virtual unsigned int CalcDiracPulsExcitation(); virtual void ApplyElectricBC(bool* dirs); //applied by default to all boundaries virtual void ApplyMagneticBC(bool* dirs); From 9fdc9096d3aafd359a7d247f64f16a65fdfe1539 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Tue, 30 Mar 2010 13:10:42 +0200 Subject: [PATCH 14/29] bugfix: length of excitation --- FDTD/engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FDTD/engine.cpp b/FDTD/engine.cpp index 15dc55b..540e0f7 100644 --- a/FDTD/engine.cpp +++ b/FDTD/engine.cpp @@ -90,7 +90,7 @@ bool Engine::IterateTS(unsigned int iterTS) for (unsigned int n=0;nE_Exc_Count;++n) { exc_pos = (int)numTS - (int)Op->E_Exc_delay[n]; - exc_pos*= (exc_pos>0 && exc_pos<(int)Op->ExciteLength); + exc_pos *= (exc_pos>0 && exc_pos<=(int)Op->ExciteLength); // if (n==0) cerr << numTS << " => " << Op->ExciteSignal[exc_pos] << endl; volt[Op->E_Exc_dir[n]][Op->E_Exc_index[0][n]][Op->E_Exc_index[1][n]][Op->E_Exc_index[2][n]] += Op->E_Exc_amp[n]*Op->ExciteSignal[exc_pos]; } From 813683304baaef989ba588f1e3557ff77c082297 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Tue, 30 Mar 2010 13:13:00 +0200 Subject: [PATCH 15/29] new commandline switch: --numThreads= --- FDTD/engine_multithread.cpp | 66 ++++++++++++++++++++++--------------- FDTD/engine_multithread.h | 20 +++++------ openems.cpp | 11 ++++++- openems.h | 1 + 4 files changed, 59 insertions(+), 39 deletions(-) diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp index e51cf25..6744d75 100644 --- a/FDTD/engine_multithread.cpp +++ b/FDTD/engine_multithread.cpp @@ -35,9 +35,10 @@ //! \brief construct an Engine_Multithread instance //! it's the responsibility of the caller to free the returned pointer -Engine_Multithread* Engine_Multithread::createEngine(Operator* op) +Engine_Multithread* Engine_Multithread::createEngine(Operator* op, unsigned int numThreads) { Engine_Multithread* e = new Engine_Multithread(op); + e->setNumThreads( numThreads ); e->Init(); return e; } @@ -66,15 +67,20 @@ Engine_Multithread::~Engine_Multithread() } +void Engine_Multithread::setNumThreads( unsigned int numThreads ) +{ + m_numThreads = numThreads; +} + void Engine_Multithread::Init() { Engine::Init(); - numTS = 0; m_numTS_times_threads = 0; // initialize threads - m_numThreads = boost::thread::hardware_concurrency(); + if (m_numThreads == 0) + m_numThreads = boost::thread::hardware_concurrency(); std::cout << "using " << m_numThreads << " threads" << std::endl; m_barrier1 = new boost::barrier(m_numThreads+1); // numThread workers + 1 excitation thread m_barrier2 = new boost::barrier(m_numThreads+1); // numThread workers + 1 excitation thread @@ -82,12 +88,13 @@ void Engine_Multithread::Init() m_startBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller m_stopBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller - for (int n=0; nnumLines[0]+m_numThreads-1) / m_numThreads; unsigned int start = n * linesPerThread; unsigned int stop = min( (n+1) * linesPerThread - 1, Op->numLines[0]-1 ); - //std::cout << "### " << Op->numLines[0] << " " << linesPerThread << " " << start << " " << stop << std::endl; - boost::thread *t = new boost::thread( thread(this,start,stop) ); + unsigned int stop_h = (n!=m_numThreads-1)?stop:stop-1; + std::cout << "###DEBUG## Thread " << n << ": start=" << start << " stop=" << stop << " stop_h=" << stop_h << std::endl; + boost::thread *t = new boost::thread( thread(this,start,stop,stop_h) ); m_thread_group.add_thread( t ); } boost::thread *t = new boost::thread( thread_e_excitation(this) ); @@ -118,11 +125,16 @@ bool Engine_Multithread::IterateTS(unsigned int iterTS) -thread::thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop ) : m_enginePtr(ptr), m_start(start), m_stop(stop), m_stopThread(false) +thread::thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop, unsigned int stop_h ) { + m_enginePtr = ptr; + m_start = start; + m_stop = stop; + m_stop_h = stop_h; Op = m_enginePtr->Op; - volt = m_enginePtr->volt; - curr = m_enginePtr->curr; + m_stopThread = false; +// volt = m_enginePtr->volt; +// curr = m_enginePtr->curr; } void thread::operator()() @@ -154,16 +166,16 @@ void thread::operator()() shift[2]=pos[2]; //do the updates here //for x - volt[0][pos[0]][pos[1]][pos[2]] *= Op->vv[0][pos[0]][pos[1]][pos[2]]; - volt[0][pos[0]][pos[1]][pos[2]] += Op->vi[0][pos[0]][pos[1]][pos[2]] * ( curr[2][pos[0]][pos[1]][pos[2]] - curr[2][pos[0]][pos[1]-shift[1]][pos[2]] - curr[1][pos[0]][pos[1]][pos[2]] + curr[1][pos[0]][pos[1]][pos[2]-shift[2]]); + m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] *= Op->vv[0][pos[0]][pos[1]][pos[2]]; + m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] += Op->vi[0][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[2][pos[0]][pos[1]-shift[1]][pos[2]] - m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]-shift[2]]); //for y - volt[1][pos[0]][pos[1]][pos[2]] *= Op->vv[1][pos[0]][pos[1]][pos[2]]; - volt[1][pos[0]][pos[1]][pos[2]] += Op->vi[1][pos[0]][pos[1]][pos[2]] * ( curr[0][pos[0]][pos[1]][pos[2]] - curr[0][pos[0]][pos[1]][pos[2]-shift[2]] - curr[2][pos[0]][pos[1]][pos[2]] + curr[2][pos[0]-shift[0]][pos[1]][pos[2]]); + m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] *= Op->vv[1][pos[0]][pos[1]][pos[2]]; + m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] += Op->vi[1][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]-shift[2]] - m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[2][pos[0]-shift[0]][pos[1]][pos[2]]); //for x - volt[2][pos[0]][pos[1]][pos[2]] *= Op->vv[2][pos[0]][pos[1]][pos[2]]; - volt[2][pos[0]][pos[1]][pos[2]] += Op->vi[2][pos[0]][pos[1]][pos[2]] * ( curr[1][pos[0]][pos[1]][pos[2]] - curr[1][pos[0]-shift[0]][pos[1]][pos[2]] - curr[0][pos[0]][pos[1]][pos[2]] + curr[0][pos[0]][pos[1]-shift[1]][pos[2]]); + m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] *= Op->vv[2][pos[0]][pos[1]][pos[2]]; + m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] += Op->vi[2][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[1][pos[0]-shift[0]][pos[1]][pos[2]] - m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[0][pos[0]][pos[1]-shift[1]][pos[2]]); } } } @@ -186,7 +198,7 @@ void thread::operator()() DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) //current updates - for (pos[0]=m_start;pos[0]<=m_stop-1;++pos[0]) + for (pos[0]=m_start;pos[0]<=m_stop_h;++pos[0]) { for (pos[1]=0;pos[1]numLines[1]-1;++pos[1]) { @@ -194,16 +206,16 @@ void thread::operator()() { //do the updates here //for x - curr[0][pos[0]][pos[1]][pos[2]] *= Op->ii[0][pos[0]][pos[1]][pos[2]]; - curr[0][pos[0]][pos[1]][pos[2]] += Op->iv[0][pos[0]][pos[1]][pos[2]] * ( volt[2][pos[0]][pos[1]][pos[2]] - volt[2][pos[0]][pos[1]+1][pos[2]] - volt[1][pos[0]][pos[1]][pos[2]] + volt[1][pos[0]][pos[1]][pos[2]+1]); + m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] *= Op->ii[0][pos[0]][pos[1]][pos[2]]; + m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] += Op->iv[0][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[2][pos[0]][pos[1]+1][pos[2]] - m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]+1]); //for y - curr[1][pos[0]][pos[1]][pos[2]] *= Op->ii[1][pos[0]][pos[1]][pos[2]]; - curr[1][pos[0]][pos[1]][pos[2]] += Op->iv[1][pos[0]][pos[1]][pos[2]] * ( volt[0][pos[0]][pos[1]][pos[2]] - volt[0][pos[0]][pos[1]][pos[2]+1] - volt[2][pos[0]][pos[1]][pos[2]] + volt[2][pos[0]+1][pos[1]][pos[2]]); + m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] *= Op->ii[1][pos[0]][pos[1]][pos[2]]; + m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] += Op->iv[1][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]+1] - m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[2][pos[0]+1][pos[1]][pos[2]]); //for x - curr[2][pos[0]][pos[1]][pos[2]] *= Op->ii[2][pos[0]][pos[1]][pos[2]]; - curr[2][pos[0]][pos[1]][pos[2]] += Op->iv[2][pos[0]][pos[1]][pos[2]] * ( volt[1][pos[0]][pos[1]][pos[2]] - volt[1][pos[0]+1][pos[1]][pos[2]] - volt[0][pos[0]][pos[1]][pos[2]] + volt[0][pos[0]][pos[1]+1][pos[2]]); + m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] *= Op->ii[2][pos[0]][pos[1]][pos[2]]; + m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] += Op->iv[2][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[1][pos[0]+1][pos[1]][pos[2]] - m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[0][pos[0]][pos[1]+1][pos[2]]); } } } @@ -226,11 +238,13 @@ void thread::operator()() } -thread_e_excitation::thread_e_excitation( Engine_Multithread* ptr ) : m_enginePtr(ptr), m_stopThread(false) +thread_e_excitation::thread_e_excitation( Engine_Multithread* ptr ) { + m_enginePtr = ptr; Op = m_enginePtr->Op; - volt = m_enginePtr->volt; - curr = m_enginePtr->curr; + m_stopThread = false; +// volt = m_enginePtr->volt; +// curr = m_enginePtr->curr; } void thread_e_excitation::operator()() @@ -251,7 +265,7 @@ void thread_e_excitation::operator()() exc_pos = (int)numTS - (int)Op->E_Exc_delay[n]; exc_pos*= (exc_pos>0 && exc_pos<(int)Op->ExciteLength); // if (n==0) cerr << numTS << " => " << Op->ExciteSignal[exc_pos] << endl; - volt[Op->E_Exc_dir[n]][Op->E_Exc_index[0][n]][Op->E_Exc_index[1][n]][Op->E_Exc_index[2][n]] += Op->E_Exc_amp[n]*Op->ExciteSignal[exc_pos]; + m_enginePtr->volt[Op->E_Exc_dir[n]][Op->E_Exc_index[0][n]][Op->E_Exc_index[1][n]][Op->E_Exc_index[2][n]] += Op->E_Exc_amp[n]*Op->ExciteSignal[exc_pos]; } // continueing thread diff --git a/FDTD/engine_multithread.h b/FDTD/engine_multithread.h index e6abbb4..12c9a8c 100644 --- a/FDTD/engine_multithread.h +++ b/FDTD/engine_multithread.h @@ -37,17 +37,13 @@ protected: class Engine_Multithread : public Engine { - friend class Processing; - friend class ProcessVoltage; - friend class ProcessCurrent; - friend class ProcessFields; - friend class ProcessFieldsTD; friend class thread; friend class thread_e_excitation; public: - static Engine_Multithread* createEngine(Operator* op); + static Engine_Multithread* createEngine(Operator* op, unsigned int numThreads = 0); virtual ~Engine_Multithread(); + virtual void setNumThreads( unsigned int numThreads ); virtual void Init(); virtual void Reset(); @@ -73,16 +69,16 @@ protected: class thread { public: - thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop ); + thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop, unsigned int stop_h ); void operator()(); protected: - unsigned int m_start, m_stop; + unsigned int m_start, m_stop, m_stop_h; volatile bool m_stopThread; Engine_Multithread *m_enginePtr; Operator *Op; - FDTD_FLOAT**** volt; - FDTD_FLOAT**** curr; +// FDTD_FLOAT**** volt; +// FDTD_FLOAT**** curr; }; class thread_e_excitation { @@ -94,8 +90,8 @@ protected: volatile bool m_stopThread; Engine_Multithread *m_enginePtr; Operator *Op; - FDTD_FLOAT**** volt; - FDTD_FLOAT**** curr; +// FDTD_FLOAT**** volt; +// FDTD_FLOAT**** curr; }; #endif // ENGINE_MULTITHREAD_H diff --git a/openems.cpp b/openems.cpp index 4fb780b..cbe374d 100644 --- a/openems.cpp +++ b/openems.cpp @@ -47,6 +47,9 @@ openEMS::openEMS() DebugMat = false; DebugOp = false; endCrit = 1e-6; + + m_engine = EngineType_Standard; + m_engine_numThreads = 0; } openEMS::~openEMS() @@ -102,6 +105,12 @@ bool openEMS::parseCommandLineArgument( const char *argv ) m_engine = EngineType_Multithreaded; return true; } + else if (strncmp(argv,"--numThreads=",13)==0) + { + m_engine_numThreads = atoi(argv+13); + cout << "openEMS - fixed number of threads: " << m_engine_numThreads << endl; + return true; + } return false; } @@ -243,7 +252,7 @@ int openEMS::SetupFDTD(const char* file) //create FDTD engine switch (m_engine) { case EngineType_Multithreaded: - FDTD_Eng = Engine_Multithread::createEngine(FDTD_Op); + FDTD_Eng = Engine_Multithread::createEngine(FDTD_Op,m_engine_numThreads); break; default: FDTD_Eng = Engine::createEngine(FDTD_Op); diff --git a/openems.h b/openems.h index d218c7a..981ac30 100644 --- a/openems.h +++ b/openems.h @@ -55,6 +55,7 @@ protected: enum EngineType {EngineType_Standard,EngineType_Multithreaded}; EngineType m_engine; + unsigned int m_engine_numThreads; }; #endif // OPENEMS_H From 3611b591e9e27d80feae6d19aa5cdea79bfd63bc Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Tue, 30 Mar 2010 13:13:27 +0200 Subject: [PATCH 16/29] bugfix matlab: single sided fft --- matlab/ReadUI.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matlab/ReadUI.m b/matlab/ReadUI.m index c4d94b1..0d79a9e 100644 --- a/matlab/ReadUI.m +++ b/matlab/ReadUI.m @@ -23,6 +23,6 @@ for n=1:numel(filenames) L=numel(val); UI.FD{n}.f = (0:L-1)/L/dt; UI.FD{n}.f = UI.FD{n}.f(1:floor(L/2)); - UI.FD{n}.val = fft(val)/L; + UI.FD{n}.val = 2*fft(val)/L; UI.FD{n}.val = UI.FD{n}.val(1:floor(L/2)); -end \ No newline at end of file +end From 50467e029debe35659a11f842436b045259bbcff Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Tue, 30 Mar 2010 13:14:00 +0200 Subject: [PATCH 17/29] new testsuite --- TESTSUITE/combinedtests/Coax.m | 152 +++++++++++++++++++ TESTSUITE/combinedtests/README | 3 + TESTSUITE/helperscripts/check_limits.m | 22 +++ TESTSUITE/helperscripts/invoke_openEMS.m | 15 ++ TESTSUITE/helperscripts/physical_constants.m | 8 + 5 files changed, 200 insertions(+) create mode 100644 TESTSUITE/combinedtests/Coax.m create mode 100644 TESTSUITE/combinedtests/README create mode 100644 TESTSUITE/helperscripts/check_limits.m create mode 100644 TESTSUITE/helperscripts/invoke_openEMS.m create mode 100644 TESTSUITE/helperscripts/physical_constants.m diff --git a/TESTSUITE/combinedtests/Coax.m b/TESTSUITE/combinedtests/Coax.m new file mode 100644 index 0000000..1ea2009 --- /dev/null +++ b/TESTSUITE/combinedtests/Coax.m @@ -0,0 +1,152 @@ +function pass = Coax + +physical_constants; + + +ENABLE_PLOTS = 1; +CLEANUP = 0; % if enabled and result is PASS, remove simulation folder +STOP_IF_FAILED = 1; % if enabled and result is FAILED, stop with error + +% LIMITS +upper_error = 0.036; % max +3.6% +lower_error = 0; % max -0.0% + +% structure +abs_length = 250; +length = 1000; +coax_rad_i = 100; +coax_rad_ai = 230; +coax_rad_aa = 240; +mesh_res = [5 5 5]; +f_start = 0; +f_stop = 1e9; + +Sim_Path = 'tmp'; +Sim_CSX = 'coax.xml'; + +[status,message,messageid]=mkdir(Sim_Path); + +%setup FDTD parameter +FDTD = InitFDTD(5e5,1e-6); +FDTD = SetGaussExcite(FDTD,(f_stop-f_start)/2,(f_stop-f_start)/2); +BC = [1 1 1 1 1 1] * 0; +FDTD = SetBoundaryCond(FDTD,BC); + +%setup CSXCAD geometry +CSX = InitCSX(); +mesh.x = -2.5*mesh_res(1)-coax_rad_aa : mesh_res(1) : coax_rad_aa+2.5*mesh_res(1); +mesh.y = mesh.x; +mesh.z = 0 : mesh_res(3) : length; +CSX = DefineRectGrid(CSX, 1e-3,mesh); + +%create copper +CSX = AddMetal(CSX,'PEC'); + +%%%fake pml +finalKappa = 0.3/abs_length^4; +finalSigma = finalKappa*MUE0/EPS0; +CSX = AddMaterial(CSX,'pml'); +CSX = SetMaterialProperty(CSX,'pml','Kappa',finalKappa); +CSX = SetMaterialProperty(CSX,'pml','Sigma',finalSigma); +CSX = SetMaterialWeight(CSX,'pml','Kappa',['pow(abs(z)-' num2str(length-abs_length) ',4)']); +CSX = SetMaterialWeight(CSX,'pml','Sigma',['pow(abs(z)-' num2str(length-abs_length) ',4)']); + +%%% coax +start = [0, 0 , 0];stop = [0, 0 , length]; +CSX = AddCylinder(CSX,'PEC',0 ,start,stop,coax_rad_i); % inner conductor +CSX = AddCylindricalShell(CSX,'PEC',0 ,start,stop,0.5*(coax_rad_aa+coax_rad_ai),(coax_rad_aa-coax_rad_ai)); % outer conductor + +%%% add PML +start(3) = length-abs_length; +CSX = AddCylindricalShell(CSX,'pml',0 ,start,stop,0.5*(coax_rad_i+coax_rad_ai),(coax_rad_ai-coax_rad_i)); +start(3) = 0; stop(3)=mesh_res(1)/2; +CSX = AddExcitation(CSX,'excite',0,[1 1 0]); +weight{1} = '(x)/(x*x+y*y)'; +weight{2} = 'y/pow(rho,2)'; +weight{3} = 0; +CSX = SetExcitationWeight(CSX, 'excite', weight ); +CSX = AddCylindricalShell(CSX,'excite',0 ,start,stop,0.5*(coax_rad_i+coax_rad_ai),(coax_rad_ai-coax_rad_i)); + +%dump +CSX = AddDump(CSX,'Et_',0,2); +start = [mesh.x(1) , 0 , mesh.z(1)]; +stop = [mesh.x(end) , 0 , mesh.z(end)]; +CSX = AddBox(CSX,'Et_',0 , start,stop); + +CSX = AddDump(CSX,'Ht_',1,2); +CSX = AddBox(CSX,'Ht_',0,start,stop); + +%voltage calc +CSX = AddProbe(CSX,'ut1',0); +start = [ coax_rad_i 0 length/2 ];stop = [ coax_rad_ai 0 length/2 ]; +CSX = AddBox(CSX,'ut1', 0 ,start,stop); + +%current calc +CSX = AddProbe(CSX,'it1',1); +mid = 0.5*(coax_rad_i+coax_rad_ai); +start = [ -mid -mid length/2 ];stop = [ mid mid length/2 ]; +CSX = AddBox(CSX,'it1', 0 ,start,stop); + +%Write openEMS compatible xml-file +WriteOpenEMS([Sim_Path '/' Sim_CSX],FDTD,CSX); + +%cd to working dir and run openEMS +savePath = pwd(); +cd(Sim_Path); %cd to working dir +invoke_openEMS( Sim_CSX ); +UI = ReadUI( {'ut1','it1'} ); +cd(savePath); + + + +% +% analysis +% + +f = UI.FD{2}.f; +u = UI.FD{1}.val; +i = UI.FD{2}.val; + +f_idx_start = interp1( f, 1:numel(f), f_start, 'nearest' ); +f_idx_stop = interp1( f, 1:numel(f), f_stop, 'nearest' ); +f = f(f_idx_start:f_idx_stop); +u = u(f_idx_start:f_idx_stop); +i = i(f_idx_start:f_idx_stop); + +Z = abs(u./i); + +% analytic formular for characteristic impedance +Z0 = sqrt(MUE0/EPS0) * log(coax_rad_ai/coax_rad_i) / (2*pi); +upper_limit = Z0 * (1+upper_error); +lower_limit = Z0 * (1-lower_error); + +if ENABLE_PLOTS + upper = upper_limit * ones(1,size(Z,2)); + lower = lower_limit * ones(1,size(Z,2)); + Z0_plot = Z0 * ones(1,size(Z,2)); + figure + plot(f/1e9,[Z;upper;lower]) + hold on + plot(f/1e9,Z0_plot,'m-.','LineWidth',2) + hold off + xlabel('Frequency (GHz)') + ylabel('Impedance (Ohm)') + legend( {'sim', 'upper limit', 'lower limit', 'theoretical'} ); +end + +pass = check_limits( Z, upper_limit, lower_limit ); +if pass + disp( 'combinedtests/Coax.m (characteristic impedance): pass' ); +else + disp( 'combinedtests/Coax.m (characteristic impedance): * FAILED *' ); +end + + + + +if pass && CLEANUP + rmdir( [Sim_Path '/' Sim_CSX], 's' ); +end +if ~pass && STOP_IF_FAILED + error 'test failed'; +end diff --git a/TESTSUITE/combinedtests/README b/TESTSUITE/combinedtests/README new file mode 100644 index 0000000..cc29c5b --- /dev/null +++ b/TESTSUITE/combinedtests/README @@ -0,0 +1,3 @@ +# +# These scripts test the full simulator (not single features) +# \ No newline at end of file diff --git a/TESTSUITE/helperscripts/check_limits.m b/TESTSUITE/helperscripts/check_limits.m new file mode 100644 index 0000000..c1cba3d --- /dev/null +++ b/TESTSUITE/helperscripts/check_limits.m @@ -0,0 +1,22 @@ +function pass = check_limits( Z, upper_limit, lower_limit ) + +% make row vector +if size(Z,1) ~= 1 + Z = Z.'; +end + +if numel(upper_limit) == 1 + upper_limit = upper_limit * ones(1,size(Z,2)); +end +if numel(lower_limit) == 1 + lower_limit = lower_limit * ones(1,size(Z,2)); +end + + +pass = 1; +if any( Z > upper_limit ) + pass = 0; +end +if any( Z < lower_limit ) + pass = 0; +end diff --git a/TESTSUITE/helperscripts/invoke_openEMS.m b/TESTSUITE/helperscripts/invoke_openEMS.m new file mode 100644 index 0000000..57f05f1 --- /dev/null +++ b/TESTSUITE/helperscripts/invoke_openEMS.m @@ -0,0 +1,15 @@ +function invoke_openEMS( opts ) + +if nargin < 1 + opts = ''; +end +% openEMS_opts = [openEMS_opts ' --disable-dumps']; +% openEMS_opts = [openEMS_opts ' --debug-material']; + +filename = mfilename('fullpath'); +dir = fileparts( filename ); +openEMS_Path = [dir '/../../']; + +command = [openEMS_Path 'openEMS.sh ' opts]; +disp(command); +system(command) diff --git a/TESTSUITE/helperscripts/physical_constants.m b/TESTSUITE/helperscripts/physical_constants.m new file mode 100644 index 0000000..082efda --- /dev/null +++ b/TESTSUITE/helperscripts/physical_constants.m @@ -0,0 +1,8 @@ +% +% physical constants +% + +% Bronstein 3rd ed., 1997, pp. 945-946 +c0 = 299792458; % m/s +MUE0 = 4e-7*pi; % N/A^2 +EPS0 = 1/(MUE0*c0^2); % F/m From 38e6c047f0f7b20c6aee8a726c4ffc7086226228 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Tue, 30 Mar 2010 15:42:01 +0200 Subject: [PATCH 18/29] testsuite: cavity (not yet finished) --- TESTSUITE/combinedtests/cavity.m | 152 +++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 TESTSUITE/combinedtests/cavity.m diff --git a/TESTSUITE/combinedtests/cavity.m b/TESTSUITE/combinedtests/cavity.m new file mode 100644 index 0000000..18310cb --- /dev/null +++ b/TESTSUITE/combinedtests/cavity.m @@ -0,0 +1,152 @@ +function pass = cavity + +physical_constants; + + +ENABLE_PLOTS = 1; +CLEANUP = 0; % if enabled and result is PASS, remove simulation folder +STOP_IF_FAILED = 1; % if enabled and result is FAILED, stop with error + +% LIMITS +upper_error = 0.036; % max +3.6% +lower_error = 0; % max -0.0% + +% structure +a = 5e-2; +b = 2e-2; +d = 6e-2; +if ~((b Date: Wed, 31 Mar 2010 15:37:39 +0200 Subject: [PATCH 19/29] bugfix: multithreaded excitation --- FDTD/engine_multithread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp index 6744d75..9e20b67 100644 --- a/FDTD/engine_multithread.cpp +++ b/FDTD/engine_multithread.cpp @@ -263,7 +263,7 @@ void thread_e_excitation::operator()() for (unsigned int n=0;nE_Exc_Count;++n) { exc_pos = (int)numTS - (int)Op->E_Exc_delay[n]; - exc_pos*= (exc_pos>0 && exc_pos<(int)Op->ExciteLength); + exc_pos*= (exc_pos>0 && exc_pos<=(int)Op->ExciteLength); // if (n==0) cerr << numTS << " => " << Op->ExciteSignal[exc_pos] << endl; m_enginePtr->volt[Op->E_Exc_dir[n]][Op->E_Exc_index[0][n]][Op->E_Exc_index[1][n]][Op->E_Exc_index[2][n]] += Op->E_Exc_amp[n]*Op->ExciteSignal[exc_pos]; } From 61f99dfd3d32e525700e9876072fb8cd7f0706c9 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Wed, 31 Mar 2010 15:38:37 +0200 Subject: [PATCH 20/29] splitted ReadUI.m into FFT_time2freq.m and itself --- matlab/FFT_time2freq.m | 9 +++++++++ matlab/ReadUI.m | 8 +------- 2 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 matlab/FFT_time2freq.m diff --git a/matlab/FFT_time2freq.m b/matlab/FFT_time2freq.m new file mode 100644 index 0000000..cdfad45 --- /dev/null +++ b/matlab/FFT_time2freq.m @@ -0,0 +1,9 @@ +function [f,val] = FFT_time2freq( t, val ) + +dt=t(2)-t(1); +val = [val zeros(1,5000)]; +L=numel(val); +f = (0:L-1)/L/dt; +f = f(1:floor(L/2)); +val = 2*fft(val)/L; +val = val(1:floor(L/2)); diff --git a/matlab/ReadUI.m b/matlab/ReadUI.m index 0d79a9e..bae9017 100644 --- a/matlab/ReadUI.m +++ b/matlab/ReadUI.m @@ -18,11 +18,5 @@ for n=1:numel(filenames) UI.TD{n}.t = t; UI.TD{n}.val = val; - dt=t(2)-t(1); - val = [val zeros(1,5000)]; - L=numel(val); - UI.FD{n}.f = (0:L-1)/L/dt; - UI.FD{n}.f = UI.FD{n}.f(1:floor(L/2)); - UI.FD{n}.val = 2*fft(val)/L; - UI.FD{n}.val = UI.FD{n}.val(1:floor(L/2)); + [UI.FD{n}.f,UI.FD{n}.val] = FFT_time2freq( t,val ); end From b5bea21529a6fc4d3299969a020299c6112d566f Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Wed, 31 Mar 2010 15:39:07 +0200 Subject: [PATCH 21/29] silence --- TESTSUITE/helperscripts/invoke_openEMS.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TESTSUITE/helperscripts/invoke_openEMS.m b/TESTSUITE/helperscripts/invoke_openEMS.m index 57f05f1..e1a4c28 100644 --- a/TESTSUITE/helperscripts/invoke_openEMS.m +++ b/TESTSUITE/helperscripts/invoke_openEMS.m @@ -12,4 +12,4 @@ openEMS_Path = [dir '/../../']; command = [openEMS_Path 'openEMS.sh ' opts]; disp(command); -system(command) +system(command); From 09bbf49b1ad6349162021cdf5c98e8fec11e33b0 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Wed, 31 Mar 2010 15:39:46 +0200 Subject: [PATCH 22/29] testsuite: new test: cavity.m (resonance frequency) --- TESTSUITE/combinedtests/cavity.m | 124 ++++++++++++++++------ TESTSUITE/helperscripts/check_frequency.m | 31 ++++++ 2 files changed, 123 insertions(+), 32 deletions(-) create mode 100644 TESTSUITE/helperscripts/check_frequency.m diff --git a/TESTSUITE/combinedtests/cavity.m b/TESTSUITE/combinedtests/cavity.m index 18310cb..39cbae9 100644 --- a/TESTSUITE/combinedtests/cavity.m +++ b/TESTSUITE/combinedtests/cavity.m @@ -7,9 +7,18 @@ ENABLE_PLOTS = 1; CLEANUP = 0; % if enabled and result is PASS, remove simulation folder STOP_IF_FAILED = 1; % if enabled and result is FAILED, stop with error -% LIMITS -upper_error = 0.036; % max +3.6% -lower_error = 0; % max -0.0% +% LIMITS - inside +lower_rel_limit = 1.3e-3; % -0.13% +upper_rel_limit = 1.3e-3; % +0.13% +lower_rel_limit_TM = 2.5e-3; % -0.25% +upper_rel_limit_TM = 0; % +0% +min_rel_amplitude = 0.6; % 60% +min_rel_amplitude_TM = 0.27; % 27% + +% LIMITS - outside +outer_rel_limit = 0.02; +max_rel_amplitude = 0.17; + % structure a = 5e-2; @@ -19,7 +28,7 @@ if ~((b f2, f2_idx = f2_idx - 1; end + + if strcmp( type, 'inside' ) + if max( val(f1_idx:f2_idx) ) < max1 * rel_amplitude + pass = false; + return + end + elseif strcmp( type, 'outside' ) + if max( val(f1_idx:f2_idx) ) > max1 * rel_amplitude + pass = false; + return + end + else + error 'unsupported operation' + end +end From 70874e56abbd87c2114f24a73a3df29cd52d58de Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Wed, 31 Mar 2010 16:35:43 +0200 Subject: [PATCH 23/29] changed some functions to const --- FDTD/engine.cpp | 4 ++-- FDTD/engine.h | 6 +++--- FDTD/operator.cpp | 4 ++-- FDTD/operator.h | 6 +++--- tools/array_ops.cpp | 8 ++++---- tools/array_ops.h | 10 +++++----- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/FDTD/engine.cpp b/FDTD/engine.cpp index 540e0f7..09c011a 100644 --- a/FDTD/engine.cpp +++ b/FDTD/engine.cpp @@ -20,14 +20,14 @@ //! \brief construct an Engine instance //! it's the responsibility of the caller to free the returned pointer -Engine* Engine::createEngine(Operator* op) +Engine* Engine::createEngine(const Operator* op) { Engine* e = new Engine(op); e->Init(); return e; } -Engine::Engine(Operator* op) +Engine::Engine(const Operator* op) { Op = op; } diff --git a/FDTD/engine.h b/FDTD/engine.h index a917686..7068ac2 100644 --- a/FDTD/engine.h +++ b/FDTD/engine.h @@ -23,7 +23,7 @@ class Engine { public: - static Engine* createEngine(Operator* op); + static Engine* createEngine(const Operator* op); virtual ~Engine(); virtual void Init(); @@ -38,8 +38,8 @@ public: virtual FDTD_FLOAT**** GetCurrents() {return curr;}; protected: - Engine(Operator* op); - Operator* Op; + Engine(const Operator* op); + const Operator* Op; FDTD_FLOAT**** volt; FDTD_FLOAT**** curr; diff --git a/FDTD/operator.cpp b/FDTD/operator.cpp index 4cd1484..bff3584 100644 --- a/FDTD/operator.cpp +++ b/FDTD/operator.cpp @@ -205,14 +205,14 @@ struct Operator::Grid_Path Operator::FindPath(double start[], double stop[]) return path; } -double Operator::GetNumberCells() +double Operator::GetNumberCells() const { if (numLines) return (numLines[0])*(numLines[1])*(numLines[2]); //it's more like number of nodes??? return 0; } -void Operator::ShowStat() +void Operator::ShowStat() const { unsigned int OpSize = 12*numLines[0]*numLines[1]*numLines[2]*sizeof(FDTD_FLOAT); unsigned int FieldSize = 6*numLines[0]*numLines[1]*numLines[2]*sizeof(FDTD_FLOAT); diff --git a/FDTD/operator.h b/FDTD/operator.h index f17197c..45b8db4 100644 --- a/FDTD/operator.h +++ b/FDTD/operator.h @@ -46,11 +46,11 @@ public: virtual void ApplyElectricBC(bool* dirs); //applied by default to all boundaries virtual void ApplyMagneticBC(bool* dirs); - double GetTimestep() {return dT;}; + double GetTimestep() const {return dT;}; unsigned int GetNyquistNum(double fmax); - double GetNumberCells(); + double GetNumberCells() const; - void ShowStat(); + void ShowStat() const; void DumpOperator2File(string filename); void DumpMaterial2File(string filename); diff --git a/tools/array_ops.cpp b/tools/array_ops.cpp index 42c010d..d80a231 100644 --- a/tools/array_ops.cpp +++ b/tools/array_ops.cpp @@ -18,7 +18,7 @@ #include "array_ops.h" #include -FDTD_FLOAT*** Create3DArray(unsigned int* numLines) +FDTD_FLOAT*** Create3DArray(const unsigned int* numLines) { FDTD_FLOAT*** array=NULL; unsigned int pos[3]; @@ -38,7 +38,7 @@ FDTD_FLOAT*** Create3DArray(unsigned int* numLines) return array; } -void Delete3DArray(FDTD_FLOAT*** array, unsigned int* numLines) +void Delete3DArray(FDTD_FLOAT*** array, const unsigned int* numLines) { if (array==NULL) return; unsigned int pos[3]; @@ -53,7 +53,7 @@ void Delete3DArray(FDTD_FLOAT*** array, unsigned int* numLines) delete[] array; } -FDTD_FLOAT**** Create_N_3DArray(unsigned int* numLines) +FDTD_FLOAT**** Create_N_3DArray(const unsigned int* numLines) { FDTD_FLOAT**** array=NULL; array = new FDTD_FLOAT***[3]; @@ -64,7 +64,7 @@ FDTD_FLOAT**** Create_N_3DArray(unsigned int* numLines) return array; } -void Delete_N_3DArray(FDTD_FLOAT**** array, unsigned int* numLines) +void Delete_N_3DArray(FDTD_FLOAT**** array, const unsigned int* numLines) { if (array==NULL) return; unsigned int pos[3]; diff --git a/tools/array_ops.h b/tools/array_ops.h index b04c821..5424e05 100644 --- a/tools/array_ops.h +++ b/tools/array_ops.h @@ -20,12 +20,12 @@ #include "../FDTD/operator.h" -FDTD_FLOAT*** Create3DArray(unsigned int* numLines); -void Delete3DArray(FDTD_FLOAT*** array, unsigned int* numLines); +FDTD_FLOAT*** Create3DArray(const unsigned int* numLines); +void Delete3DArray(FDTD_FLOAT*** array, const unsigned int* numLines); -FDTD_FLOAT**** Create_N_3DArray(unsigned int* numLines); -void Delete_N_3DArray(FDTD_FLOAT**** array, unsigned int* numLines); +FDTD_FLOAT**** Create_N_3DArray(const unsigned int* numLines); +void Delete_N_3DArray(FDTD_FLOAT**** array, const unsigned int* numLines); -void Dump_N_3DArray2File(ostream &file, FDTD_FLOAT**** array, unsigned int* numLines); +void Dump_N_3DArray2File(ostream &file, FDTD_FLOAT**** array, const unsigned int* numLines); #endif // ARRAY_OPS_H From f7a17f3678be77e6c782ee0aad2b51acac58e9d6 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Thu, 1 Apr 2010 09:38:08 +0200 Subject: [PATCH 24/29] bugfix: SetProcessInterval --- FDTD/processing.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FDTD/processing.h b/FDTD/processing.h index a5cd4e3..f9dd017 100644 --- a/FDTD/processing.h +++ b/FDTD/processing.h @@ -31,7 +31,7 @@ public: virtual void DefineStartStopCoord(double* dstart, double* dstop); - void SetProcessInterval(unsigned int interval) {ProcessInterval=interval;} + void SetProcessInterval(unsigned int interval) {ProcessInterval=max((unsigned int)1,interval);} virtual int Process() {return GetNextInterval();} //! If Disabled Process() will do nothing... From 98063bba6e8cd0b756d4fc767e7c40b58e6e68fe Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Thu, 1 Apr 2010 09:38:56 +0200 Subject: [PATCH 25/29] new excitation step --- FDTD/operator.cpp | 23 +++++++++++++++++++++-- FDTD/operator.h | 3 +++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/FDTD/operator.cpp b/FDTD/operator.cpp index bff3584..2fd1638 100644 --- a/FDTD/operator.cpp +++ b/FDTD/operator.cpp @@ -253,13 +253,32 @@ unsigned int Operator::CalcDiracPulsExcitation() if (dT==0) return 0; ExciteLength = 1; - cerr << "Operator::CalcDiracPulsExcitation: Length of the excite signal: " << ExciteLength << " timesteps" << endl; +// cerr << "Operator::CalcDiracPulsExcitation: Length of the excite signal: " << ExciteLength << " timesteps" << endl; delete[] ExciteSignal; ExciteSignal = new FDTD_FLOAT[ExciteLength+1]; ExciteSignal[0]=0.0; ExciteSignal[1]=1.0; - return 1; + // FIXME GetNyquistNum() has side-effects! + m_nyquistTS = 1; + + return m_nyquistTS; +} + +unsigned int Operator::CalcStepExcitation() +{ + if (dT==0) return 0; + + ExciteLength = 1; + delete[] ExciteSignal; + ExciteSignal = new FDTD_FLOAT[ExciteLength+1]; + ExciteSignal[0]=1.0; + ExciteSignal[1]=1.0; + + // FIXME GetNyquistNum() has side-effects! + m_nyquistTS = 1; + + return m_nyquistTS; } unsigned int Operator::CalcSinusExcitation(double f0, int nTS) diff --git a/FDTD/operator.h b/FDTD/operator.h index 45b8db4..fab5c27 100644 --- a/FDTD/operator.h +++ b/FDTD/operator.h @@ -41,7 +41,10 @@ public: virtual unsigned int CalcGaussianPulsExcitation(double f0, double fc); //! Calculate a sinusoidal excitation with frequency f0 and a duration of nTS number of timesteps \return number of Nyquist timesteps virtual unsigned int CalcSinusExcitation(double f0, int nTS); + //! Calculate a dirac impuls excitation \return number of Nyquist timesteps virtual unsigned int CalcDiracPulsExcitation(); + //! Calculate a step excitation \return number of Nyquist timesteps + virtual unsigned int CalcStepExcitation(); virtual void ApplyElectricBC(bool* dirs); //applied by default to all boundaries virtual void ApplyMagneticBC(bool* dirs); From b0f0803efd4d6409f869058fc43494f609e2a325 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Thu, 1 Apr 2010 09:39:12 +0200 Subject: [PATCH 26/29] matlab: help added --- matlab/SetBoundaryCond.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/matlab/SetBoundaryCond.m b/matlab/SetBoundaryCond.m index 6d1ba6d..ed5ba8c 100644 --- a/matlab/SetBoundaryCond.m +++ b/matlab/SetBoundaryCond.m @@ -1,4 +1,8 @@ function FDTD = SetBoundaryCond(FDTD,BC) +% FDTD = SetBoundaryCond(FDTD,BC) +% +% BC = [xmin xmax ymin ymax zmin zmax]; +% ?min/?max: 0=PEC 1=PMC FDTD.BoundaryCond.ATTRIBUTE.xmin=BC(1); FDTD.BoundaryCond.ATTRIBUTE.xmax=BC(2); From 60cc15e94690c840d7f8018368646e362cb81e77 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Thu, 1 Apr 2010 09:39:27 +0200 Subject: [PATCH 27/29] new excitation --- openems.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/openems.cpp b/openems.cpp index cbe374d..9115eb3 100644 --- a/openems.cpp +++ b/openems.cpp @@ -174,6 +174,11 @@ int openEMS::SetupFDTD(const char* file) Excite->QueryDoubleAttribute("f0",&f0); fc = 0; } + else if (Excit_Type==2) + { + Excite->QueryDoubleAttribute("f0",&f0); + fc = 0; + } TiXmlElement* BC = FDTD_Opts->FirstChildElement("BoundaryCond"); if (BC==NULL) @@ -226,6 +231,24 @@ int openEMS::SetupFDTD(const char* file) exit(2); } } + else if (Excit_Type==2) + { + Nyquist = FDTD_Op->CalcDiracPulsExcitation(); + if (!Nyquist) + { + cerr << "openEMS: excitation setup failed!!" << endl; + exit(2); + } + } + else if (Excit_Type==3) + { + Nyquist = FDTD_Op->CalcStepExcitation(); + if (!Nyquist) + { + cerr << "openEMS: excitation setup failed!!" << endl; + exit(2); + } + } else { cerr << "openEMS: Excitation type is unknown" << endl; From b9dea986870429e89710e156a12b649717c02a5c Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Thu, 1 Apr 2010 16:11:25 +0200 Subject: [PATCH 28/29] bugfix: delete sequence violated --- openems.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/openems.cpp b/openems.cpp index 9115eb3..2beb857 100644 --- a/openems.cpp +++ b/openems.cpp @@ -54,23 +54,15 @@ openEMS::openEMS() openEMS::~openEMS() { - delete FDTD_Eng; - FDTD_Eng=NULL; - delete PA; - PA=NULL; - delete FDTD_Op; - FDTD_Op=NULL; + Reset(); } void openEMS::Reset() { - delete FDTD_Op; - FDTD_Op=NULL; - delete FDTD_Eng; - FDTD_Eng=NULL; if (PA) PA->DeleteAll(); - delete PA; - PA=NULL; + delete PA; PA=0; + delete FDTD_Eng; FDTD_Eng=0; + delete FDTD_Op; FDTD_Op=0; } //! \brief processes a command line argument From 37ff221c18fcbeddf62944a9d72381dbe75e57cb Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Thu, 1 Apr 2010 16:11:55 +0200 Subject: [PATCH 29/29] multithreaded engine works but it's slow... --- FDTD/engine_multithread.cpp | 159 +++++++++++++++++++++--------------- FDTD/engine_multithread.h | 90 ++++++++++---------- 2 files changed, 139 insertions(+), 110 deletions(-) diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp index 9e20b67..42ab92a 100644 --- a/FDTD/engine_multithread.cpp +++ b/FDTD/engine_multithread.cpp @@ -32,10 +32,9 @@ #include "boost/date_time/gregorian/gregorian.hpp" #include - //! \brief construct an Engine_Multithread instance //! it's the responsibility of the caller to free the returned pointer -Engine_Multithread* Engine_Multithread::createEngine(Operator* op, unsigned int numThreads) +Engine_Multithread* Engine_Multithread::createEngine(const Operator* op, unsigned int numThreads) { Engine_Multithread* e = new Engine_Multithread(op); e->setNumThreads( numThreads ); @@ -43,28 +42,29 @@ Engine_Multithread* Engine_Multithread::createEngine(Operator* op, unsigned int return e; } -Engine_Multithread::Engine_Multithread(Operator* op) : Engine(op) +Engine_Multithread::Engine_Multithread(const Operator* op) : Engine(op) { } Engine_Multithread::~Engine_Multithread() { #ifdef ENABLE_DEBUG_TIME - cout << "Engine_Multithread::~Engine_Multithread()" << endl; + NS_Engine_Multithread::DBG().cout() << "Engine_Multithread::~Engine_Multithread()" << endl; std::map >::iterator it; for (it=m_timer_list.begin(); it!=m_timer_list.end(); it++) { - std::cout << "*** DEBUG Thread: " << it->first << std::endl; + NS_Engine_Multithread::DBG().cout() << "*** DEBUG Thread: " << it->first << std::endl; std::vector::iterator it2; for (it2=it->second.begin(); it2second.end();) { - std::cout << "after voltage update, before barrier1: " << fixed << setprecision(6) << *(it2++) << std::endl; - std::cout << "after barrier1, before barrier2: " << fixed << setprecision(6) << *(it2++) << std::endl; - std::cout << "after barrier2, before current update: " << fixed << setprecision(6) << *(it2++) << std::endl; - std::cout << "after current update, before barrier3: " << fixed << setprecision(6) << *(it2++) << std::endl; - std::cout << "after barrier3: " << fixed << setprecision(6) << *(it2++) << std::endl; + NS_Engine_Multithread::DBG().cout() << "after voltage update, before barrier1: " << fixed << setprecision(6) << *(it2++) << std::endl; + NS_Engine_Multithread::DBG().cout() << "after barrier1, before barrier2: " << fixed << setprecision(6) << *(it2++) << std::endl; + NS_Engine_Multithread::DBG().cout() << "after barrier2, before current update: " << fixed << setprecision(6) << *(it2++) << std::endl; + NS_Engine_Multithread::DBG().cout() << "after current update, before barrier3: " << fixed << setprecision(6) << *(it2++) << std::endl; + NS_Engine_Multithread::DBG().cout() << "after barrier3: " << fixed << setprecision(6) << *(it2++) << std::endl; } } #endif + Reset(); } void Engine_Multithread::setNumThreads( unsigned int numThreads ) @@ -74,35 +74,55 @@ void Engine_Multithread::setNumThreads( unsigned int numThreads ) void Engine_Multithread::Init() { - Engine::Init(); - - m_numTS_times_threads = 0; + Engine::Init(); // gets cleaned up by Engine::~Engine() // initialize threads + m_stopThreads = false; if (m_numThreads == 0) m_numThreads = boost::thread::hardware_concurrency(); - std::cout << "using " << m_numThreads << " threads" << std::endl; + cout << "using " << m_numThreads << " threads" << std::endl; m_barrier1 = new boost::barrier(m_numThreads+1); // numThread workers + 1 excitation thread m_barrier2 = new boost::barrier(m_numThreads+1); // numThread workers + 1 excitation thread m_barrier3 = new boost::barrier(m_numThreads); // numThread workers m_startBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller m_stopBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller + unsigned int linesPerThread = round((float)Op->numLines[0] / (float)m_numThreads); for (unsigned int n=0; nnumLines[0]+m_numThreads-1) / m_numThreads; unsigned int start = n * linesPerThread; - unsigned int stop = min( (n+1) * linesPerThread - 1, Op->numLines[0]-1 ); - unsigned int stop_h = (n!=m_numThreads-1)?stop:stop-1; - std::cout << "###DEBUG## Thread " << n << ": start=" << start << " stop=" << stop << " stop_h=" << stop_h << std::endl; - boost::thread *t = new boost::thread( thread(this,start,stop,stop_h) ); + unsigned int stop = (n+1) * linesPerThread - 1; + unsigned int stop_h = stop; + if (n == m_numThreads-1) { + // last thread + stop = Op->numLines[0]-1; + stop_h = stop-1; + } + //NS_Engine_Multithread::DBG().cout() << "###DEBUG## Thread " << n << ": start=" << start << " stop=" << stop << " stop_h=" << stop_h << std::endl; + boost::thread *t = new boost::thread( NS_Engine_Multithread::thread(this,start,stop,stop_h,n) ); m_thread_group.add_thread( t ); } - boost::thread *t = new boost::thread( thread_e_excitation(this) ); + boost::thread *t = new boost::thread( NS_Engine_Multithread::thread_e_excitation(this) ); m_thread_group.add_thread( t ); } void Engine_Multithread::Reset() { + if (!m_stopThreads) { + // prevent multiple invocations + + // stop the threads + //NS_Engine_Multithread::DBG().cout() << "stopping all threads" << endl; + m_iterTS = 1; + m_startBarrier->wait(); // start the threads + m_stopThreads = true; + m_stopBarrier->wait(); // wait for the threads to finish + m_thread_group.join_all(); // wait for termination + delete m_barrier1; m_barrier1 = 0; + delete m_barrier2; m_barrier2 = 0; + delete m_barrier3; m_barrier3 = 0; + delete m_startBarrier; m_startBarrier = 0; + delete m_stopBarrier; m_stopBarrier = 0; + } Engine::Reset(); } @@ -110,43 +130,41 @@ void Engine_Multithread::Reset() bool Engine_Multithread::IterateTS(unsigned int iterTS) { m_iterTS = iterTS; + //cout << "bool Engine_Multithread::IterateTS(): starting threads ..."; m_startBarrier->wait(); // start the threads + //cout << "... threads started"; m_stopBarrier->wait(); // wait for the threads to finish time steps - numTS = m_numTS_times_threads / m_numThreads; return true; } +// +// ************************************************************************************************************************* +// +namespace NS_Engine_Multithread { - - - - - -thread::thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop, unsigned int stop_h ) +thread::thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop, unsigned int stop_h, unsigned int threadID ) { m_enginePtr = ptr; m_start = start; m_stop = stop; m_stop_h = stop_h; - Op = m_enginePtr->Op; - m_stopThread = false; -// volt = m_enginePtr->volt; -// curr = m_enginePtr->curr; + m_threadID = threadID; } void thread::operator()() { //std::cout << "thread::operator() Parameters: " << m_start << " " << m_stop << std::endl; + //DBG().cout() << "Thread " << m_threadID << " (" << boost::this_thread::get_id() << ") started." << endl; unsigned int pos[3]; bool shift[3]; - while (!m_stopThread) { + while (!m_enginePtr->m_stopThreads) { // wait for start - //cout << "Thread " << boost::this_thread::get_id() << " waiting..." << endl; + //DBG().cout() << "Thread " << m_threadID << " (" << boost::this_thread::get_id() << ") waiting..." << endl; m_enginePtr->m_startBarrier->wait(); //cout << "Thread " << boost::this_thread::get_id() << " waiting... started." << endl; @@ -158,24 +176,24 @@ void thread::operator()() for (pos[0]=m_start;pos[0]<=m_stop;++pos[0]) { shift[0]=pos[0]; - for (pos[1]=0;pos[1]numLines[1];++pos[1]) + for (pos[1]=0;pos[1]Op->numLines[1];++pos[1]) { shift[1]=pos[1]; - for (pos[2]=0;pos[2]numLines[2];++pos[2]) + for (pos[2]=0;pos[2]Op->numLines[2];++pos[2]) { shift[2]=pos[2]; //do the updates here //for x - m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] *= Op->vv[0][pos[0]][pos[1]][pos[2]]; - m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] += Op->vi[0][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[2][pos[0]][pos[1]-shift[1]][pos[2]] - m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]-shift[2]]); + m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] *= m_enginePtr->Op->vv[0][pos[0]][pos[1]][pos[2]]; + m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] += m_enginePtr->Op->vi[0][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[2][pos[0]][pos[1]-shift[1]][pos[2]] - m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]-shift[2]]); //for y - m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] *= Op->vv[1][pos[0]][pos[1]][pos[2]]; - m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] += Op->vi[1][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]-shift[2]] - m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[2][pos[0]-shift[0]][pos[1]][pos[2]]); + m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] *= m_enginePtr->Op->vv[1][pos[0]][pos[1]][pos[2]]; + m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] += m_enginePtr->Op->vi[1][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]-shift[2]] - m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[2][pos[0]-shift[0]][pos[1]][pos[2]]); //for x - m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] *= Op->vv[2][pos[0]][pos[1]][pos[2]]; - m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] += Op->vi[2][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[1][pos[0]-shift[0]][pos[1]][pos[2]] - m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[0][pos[0]][pos[1]-shift[1]][pos[2]]); + m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] *= m_enginePtr->Op->vv[2][pos[0]][pos[1]][pos[2]]; + m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] += m_enginePtr->Op->vi[2][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[1][pos[0]-shift[0]][pos[1]][pos[2]] - m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[0][pos[0]][pos[1]-shift[1]][pos[2]]); } } } @@ -200,22 +218,22 @@ void thread::operator()() //current updates for (pos[0]=m_start;pos[0]<=m_stop_h;++pos[0]) { - for (pos[1]=0;pos[1]numLines[1]-1;++pos[1]) + for (pos[1]=0;pos[1]Op->numLines[1]-1;++pos[1]) { - for (pos[2]=0;pos[2]numLines[2]-1;++pos[2]) + for (pos[2]=0;pos[2]Op->numLines[2]-1;++pos[2]) { //do the updates here //for x - m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] *= Op->ii[0][pos[0]][pos[1]][pos[2]]; - m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] += Op->iv[0][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[2][pos[0]][pos[1]+1][pos[2]] - m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]+1]); + m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] *= m_enginePtr->Op->ii[0][pos[0]][pos[1]][pos[2]]; + m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] += m_enginePtr->Op->iv[0][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[2][pos[0]][pos[1]+1][pos[2]] - m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]+1]); //for y - m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] *= Op->ii[1][pos[0]][pos[1]][pos[2]]; - m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] += Op->iv[1][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]+1] - m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[2][pos[0]+1][pos[1]][pos[2]]); + m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] *= m_enginePtr->Op->ii[1][pos[0]][pos[1]][pos[2]]; + m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] += m_enginePtr->Op->iv[1][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]+1] - m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[2][pos[0]+1][pos[1]][pos[2]]); //for x - m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] *= Op->ii[2][pos[0]][pos[1]][pos[2]]; - m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] += Op->iv[2][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[1][pos[0]+1][pos[1]][pos[2]] - m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[0][pos[0]][pos[1]+1][pos[2]]); + m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] *= m_enginePtr->Op->ii[2][pos[0]][pos[1]][pos[2]]; + m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] += m_enginePtr->Op->iv[2][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[1][pos[0]+1][pos[1]][pos[2]] - m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[0][pos[0]][pos[1]+1][pos[2]]); } } } @@ -230,45 +248,54 @@ void thread::operator()() //soft current excitation here (H-field excite) - ++m_enginePtr->m_numTS_times_threads; + if (m_threadID == 0) + ++m_enginePtr->numTS; // only the first thread increments numTS } m_enginePtr->m_stopBarrier->wait(); } + + //DBG().cout() << "Thread " << m_threadID << " (" << boost::this_thread::get_id() << ") finished." << endl; } +} // namespace + +// +// ************************************************************************************************************************* +// +namespace NS_Engine_Multithread { thread_e_excitation::thread_e_excitation( Engine_Multithread* ptr ) { m_enginePtr = ptr; - Op = m_enginePtr->Op; - m_stopThread = false; -// volt = m_enginePtr->volt; -// curr = m_enginePtr->curr; } void thread_e_excitation::operator()() { //std::cout << "thread_e_excitation::operator()" << std::endl; + //DBG().cout() << "Thread e_excitation (" << boost::this_thread::get_id() << ") started." << endl; - while (!m_stopThread) { + int exc_pos; + const unsigned int E_Exc_Count = m_enginePtr->Op->E_Exc_Count; - // waiting on thread + while (!m_enginePtr->m_stopThreads) + { + // waiting on NS_Engine_Multithread::thread m_enginePtr->m_barrier1->wait(); - int exc_pos; - unsigned int numTS = m_enginePtr->m_numTS_times_threads / m_enginePtr->m_numThreads; - - //soft voltage excitation here (E-field excite) - for (unsigned int n=0;nE_Exc_Count;++n) + // soft voltage excitation here (E-field excite) + for (unsigned int n=0;nE_Exc_delay[n]; - exc_pos*= (exc_pos>0 && exc_pos<=(int)Op->ExciteLength); - // if (n==0) cerr << numTS << " => " << Op->ExciteSignal[exc_pos] << endl; - m_enginePtr->volt[Op->E_Exc_dir[n]][Op->E_Exc_index[0][n]][Op->E_Exc_index[1][n]][Op->E_Exc_index[2][n]] += Op->E_Exc_amp[n]*Op->ExciteSignal[exc_pos]; + exc_pos = (int)m_enginePtr->numTS - (int)m_enginePtr->Op->E_Exc_delay[n]; + exc_pos*= (exc_pos>0 && exc_pos<=(int)m_enginePtr->Op->ExciteLength); + m_enginePtr->volt[m_enginePtr->Op->E_Exc_dir[n]][m_enginePtr->Op->E_Exc_index[0][n]][m_enginePtr->Op->E_Exc_index[1][n]][m_enginePtr->Op->E_Exc_index[2][n]] += m_enginePtr->Op->E_Exc_amp[n]*m_enginePtr->Op->ExciteSignal[exc_pos]; } - // continueing thread + // continue NS_Engine_Multithread::thread m_enginePtr->m_barrier2->wait(); } + + //DBG().cout() << "Thread e_excitation (" << boost::this_thread::get_id() << ") finished." << endl; } + +} // namespace diff --git a/FDTD/engine_multithread.h b/FDTD/engine_multithread.h index 12c9a8c..ef3623d 100644 --- a/FDTD/engine_multithread.h +++ b/FDTD/engine_multithread.h @@ -26,21 +26,54 @@ #include #include -//debug -class Timer { -public: - Timer() {gettimeofday(&t1,NULL);} - double elapsed() {gettimeofday(&t2,NULL); return (t2.tv_sec-t1.tv_sec) + (t2.tv_usec-t1.tv_usec)*1e-6;} -protected: - timeval t1,t2; -}; +class Engine_Multithread; + +namespace NS_Engine_Multithread { + + class DBG { // debug + public: + DBG() {} + ~DBG() { std::cout << os.str();} + std::ostringstream& cout() {return os;} + protected: + std::ostringstream os; + }; + + class Timer { //debug + public: + Timer() {gettimeofday(&t1,NULL);} + double elapsed() {gettimeofday(&t2,NULL); return (t2.tv_sec-t1.tv_sec) + (t2.tv_usec-t1.tv_usec)*1e-6;} + protected: + timeval t1,t2; + }; + + class thread { + public: + thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop, unsigned int stop_h, unsigned int threadID ); + void operator()(); + + protected: + unsigned int m_start, m_stop, m_stop_h, m_threadID; + Engine_Multithread *m_enginePtr; + }; + + class thread_e_excitation { + public: + thread_e_excitation( Engine_Multithread* ptr); + void operator()(); + + protected: + Engine_Multithread *m_enginePtr; + }; +} // namespace + class Engine_Multithread : public Engine { - friend class thread; - friend class thread_e_excitation; + friend class NS_Engine_Multithread::thread; + friend class NS_Engine_Multithread::thread_e_excitation; public: - static Engine_Multithread* createEngine(Operator* op, unsigned int numThreads = 0); + static Engine_Multithread* createEngine(const Operator* op, unsigned int numThreads = 0); virtual ~Engine_Multithread(); virtual void setNumThreads( unsigned int numThreads ); @@ -50,48 +83,17 @@ public: //!Iterate a number of timesteps virtual bool IterateTS(unsigned int iterTS); - virtual unsigned int GetNumberOfTimesteps() {return m_numTS_times_threads / m_numThreads;} - protected: - Engine_Multithread(Operator* op); + Engine_Multithread(const Operator* op); boost::thread_group m_thread_group; boost::barrier *m_barrier1, *m_barrier2, *m_barrier3, *m_startBarrier, *m_stopBarrier; volatile unsigned int m_iterTS; - volatile unsigned int m_numTS_times_threads; //!< numTS times the number of worker threads unsigned int m_numThreads; //!< number of worker threads + volatile bool m_stopThreads; #ifdef ENABLE_DEBUG_TIME std::map > m_timer_list; #endif }; - - -class thread { -public: - thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop, unsigned int stop_h ); - void operator()(); - -protected: - unsigned int m_start, m_stop, m_stop_h; - volatile bool m_stopThread; - Engine_Multithread *m_enginePtr; - Operator *Op; -// FDTD_FLOAT**** volt; -// FDTD_FLOAT**** curr; -}; - -class thread_e_excitation { -public: - thread_e_excitation( Engine_Multithread* ptr); - void operator()(); - -protected: - volatile bool m_stopThread; - Engine_Multithread *m_enginePtr; - Operator *Op; -// FDTD_FLOAT**** volt; -// FDTD_FLOAT**** curr; -}; - #endif // ENGINE_MULTITHREAD_H