Page 1 of 2

Periodic Boundary Conditions (PBC)

Posted: Mon 29 May 2017, 09:52
by LowDepth
Hello everyone,
I have just started working on periodic boundary conditions for openEMS.
During my research on the literature I came across this paper:
http://ieeexplore.ieee.org/stamp/stamp. ... 8378&tag=1
and I plan to implement something along those lines.

It would be great if anyone also interested in this topic would share her/his opinion about what kind of implementation of the PBCs would be the "best". Furthermore any kind of help is appreciated!

I am able to build openEMS from the master branch of:
https://github.com/thliebig/openEMS-Project
using qtcreator on Ubuntu 16.04. Furthermore I have verified that the built executables substitute the ones in my openEMS "run-path", so that the bash command

Code: Select all

~$ openEMS
really executes the freshly built openEMS.

Re: Periodic Boundary Conditions (PBC)

Posted: Tue 30 May 2017, 19:36
by thorsten
During my research on the literature I came across this paper:
Did you have a look how meep has implemented the PBC?

In any case it would be an idea to setup a simulation in both tools using PBC for comparison?

regards
Thorsten

Re: Periodic Boundary Conditions (PBC)

Posted: Tue 30 May 2017, 19:46
by thorsten
Additionally I strongly recommend you study our paper on openEMS as it talks about how the EC-FDTD differs somewhat from a "normal" FDTD.
Most importantly the engine (and extensions) uses voltages and currents instead of E- and H-fields. But this is a trivial difference as these are just E- and H-fields multiplied by the edge length.
But you have to keep all this in mind as it required to change the used formulas to make it EC (equivalent circuit).

Furthermore you should study the header file for the FDTD operator class as it provides many useful function to e.g. access grid quantities like edge length or node areas and so on... After all openEMS does support inhomogeneous meshes and you do not want (and should not) calculate all this quantities yourself...

Re: Periodic Boundary Conditions (PBC)

Posted: Tue 20 Jun 2017, 08:15
by LowDepth
Dear Thorsten,
I have forked openEMS.git from your github repository and created 4 files in FDTD/extensions:
- operator_ext_pbc.cpp
- operator_ext_pbc.h
- engine_ext_pbc.cpp
- engine_ext_pbc.h

Furthermore I added the *.cpp files to CMakeLists.txt in directory FDTD/extensions. The *.cpp source files,
however, are empty so far.
Questions:
1.
Before I proceed I would like to ask if its your preferred
way of development, if I try to establish the periodic boundary conditions in my forked repository.

2.
My next step would be to define the Do(Pre)VoltageUpdates in order to add the phase difference between
the opposite sides of the surfaces where PBC are to be applied. Do you think the Engine_Ext_UPML would be a
good starting point?

3.
How do I have to take care about CylindricalCoordinates and the different engine types (SSE, Multithreaded, etc)?

Best regards
Stefan

Re: Periodic Boundary Conditions (PBC)

Posted: Tue 20 Jun 2017, 17:11
by thorsten
Hi,

your approach sounds solid. But keep in mind that you not only need to define the extension, you must make it instanced/used at some point during the setup.
Do you think the Engine_Ext_UPML would be a good starting point?
Well no not the best. The PML is quite complex and I kind of had to "abuse" the extension concept somewhat.
For example the "DoPreVoltageUpdates" and "DoPostVoltageUpdates" are meant to read only access the fields. And the "Apply2Voltages" method may be the only one to change the voltages.
(The same with the currents). The PML extension kind of does not obey this rule, but you should.

The MUR absorbing boundary conditions may be a better choice?
How do I have to take care about CylindricalCoordinates and the different engine types (SSE, Multithreaded, etc)?
For now you should not care about the engine type but use the main access functions. E.g. like here: https://github.com/thliebig/openEMS/blo ... c.cpp#L250
Later on you may add a way to access the field more direct for the different types of engine.

The same for the cylindrical coordinates. If you only use high level function of the operator and engine, chances are your new extension will just work with cylindrical mesh too. But lets worry about that later too..

regards
Thorsten

Re: Periodic Boundary Conditions (PBC)

Posted: Tue 01 Aug 2017, 13:22
by LowDepth
Meanwhile I did some progress in the understanding of the CTW (constant transverse wavenumber) approach.
I think there is no way to avoid introducing complex currents and voltages. Thorsten, how nasty would you estimate the side effects of doing this?


Best regards

Re: Periodic Boundary Conditions (PBC)

Posted: Tue 01 Aug 2017, 17:59
by thorsten
I think there is no way to avoid introducing complex currents and voltages.
WTF? :shock:
Thorsten, how nasty would you estimate the side effects of doing this?
I have no idea, but I'm pretty sure that these additional voltages and currents need to stay inside the PBC extension.
That said, ideally you can just express the imaginary part as additional voltages/currents only and purely hidden away inside the extension.
But this already sounds like that such an extension would not really be compatibly to intersect with any other extention?

Do you already have an idea how to express this PBC in terms of the EC (equivalent circuit) formulation as used by openEMS?

regards
Thorsten

Re: Periodic Boundary Conditions (PBC)

Posted: Wed 20 Sep 2017, 13:02
by LowDepth
Do you already have an idea how to express this PBC in terms of the EC (equivalent circuit) formulation as used by openEMS?
If we have periodicity in x-direction and we one have complex quantities I would just set the voltages as voltage[0/1/2][0][0][0] = voltage[0/1/2][numX][0][0] * exp(I*kx*L) and would do the same for the currents
By the way... I think PEC is the default BC, but so far I somehow miss the position in your code, where the voltage is set to zero, if we arrive at the boundary of the simulation region.

That said, ideally you can just express the imaginary part as additional voltages/currents only and purely hidden away inside the extension.
The reason for this is because for example in

Code: Select all

void Engine::DoPreVoltageUpdates()
{
	//execute extensions in reverse order -> highest priority gets access to the voltages last
	for (int n=m_Eng_exts.size()-1; n>=0; --n)
		m_Eng_exts.at(n)->DoPreVoltageUpdates();

}
We execute each engine_extension's "DoPostVoltageUpdates()" method to operate on our voltages and complex quantities would mean, that one would have to adopt every single extension, right?

By the way, what is the idea behind the "name convention" with the starting "m_" like "m_Engine", "m_nyP" and "m_nyPP", "M_LineNr" and so on...?


Best regards

Re: Periodic Boundary Conditions (PBC)

Posted: Wed 20 Sep 2017, 18:03
by thorsten
If we have periodicity in x-direction and we one have complex quantities I would just set the voltages as voltage[0/1/2][0][0][0] = voltage[0/1/2][numX][0][0] * exp(I*kx*L) and would do the same for the currents
I do not think this is a good idea as the voltages are just floats and cannot handle complex values. And I still don't see why you would need complex values. Complex numbers are for FD solver, and have nothing to do with TD?
The FDTD method used ADE (additional differential equations) to solve all kind of models that would require complex values in FD solver. I'm still not convinced that this is a valid approach? Maybe you can elaborate again why you need complex numbers in time domain??
As far as I have understood PBC you have to store values to apply later to simulate a time delay...
I think PEC is the default BC, but so far I somehow miss the position in your code, where the voltage is set to zero, if we arrive at the boundary of the simulation region.
They are never set as all voltages (and currents) are initialized as zero and the engine just never is able to change the values and additonally the operator for the boundaries is zero too.
We execute each engine_extension's "DoPostVoltageUpdates()" method to operate on our voltages and complex quantities would mean, that one would have to adopt every single extension, right?
No extension may force any other extension or the main engine to do anything differently as the normal FDTD algorithm requires. Again, the "normal" voltages and currents must remain time domain float and real quantities. Everything else does make no sense... You PBC may contain additional values of course and do with them what it wants. And it is very much possible that other extensions may not be compatible with the PBC and thus may not overlap with them.

Code: Select all

By the way, what is the idea behind the "name convention" with the starting "m_" like "m_Engine", "m_nyP" and "m_nyPP", "M_LineNr" and so on...?
The m_* are "member" variables of that class. "g_*" would be global variables. And without a prefix would be local variables (only within that function or method). But I was never really that consistent with this...

regards
Thorsten

Re: Periodic Boundary Conditions (PBC)

Posted: Thu 21 Sep 2017, 15:08
by LowDepth
Maybe you can elaborate again why you need complex numbers in time domain??
the problem is that wheres for L-periodic structures in x-direction we would encounter a phase shift of the fields in frequency domain: u(x=0) = u(x=L) * exp(I * kx * L), for the pulses used in FDTD we would have a time shift in time-domain, which would sometimes involve fields at later times to do the updates and which would be furthermore frequency dependent.
The PBC I am trying to implement solves the problem of frequency-dependence by injecting a plane wave pulse into the simulation volume, which posseses a frequency-independent parallel wave-vector.
For a periodicity of Lx in x-direction this means in time domain: u(x=0, y, t+1) = A*sin(kx*Lx) * u(x=L, y, t) + B *cos(kx*Lx) * u(x=L,y, t). But the "weights" A and B of the sine and the cosine are not known apriori.
While writing I realize, that maybe it would be doable what you suggested earlier... to keep the real fields known to the main engine and multiply them by cos(kx * L) and save new values inside the extension, which would involve a multiplication by sin(kx * L).
See for example the book "Advances in FDTD Computational Electrodynamics: Photonics and Nanotechnology" page 84... the key-word is "Bloch-Waves" : https://books.google.de/books?id=ynRM33 ... td&f=false]

At the moment I think one may initialize the real part as usual and once we reach one side of the computational grid, we obtain an imaginary part which is cos(kx * Lx) the real-part and and from there on each further timestep includes "mixing" between imaginary and real parts by means of multiplications by sin(kx * Lx) / cos(kx * Lx)

They are never set as all voltages (and currents) are initialized as zero and the engine just never is able to change the values and additonally the operator for the boundaries is zero too.
Let me elaborate on this to see if I understood correctly:
Since for example Ux(t+1,nx,ny,nz) only depends on Ux(t,nx,ny,nz) and Ix(t, nx, ny-1, nz-1) it needs: Ux(t,nx,ny,nz) = Ix(t, nx, ny-1, nz-1) = 0 in order for Ux(t,nx,ny,nz) = 0 for all timesteps.
What you say is, that for example Ux(., 0,ny,nz), U(.,nx,0,nz) and U(.,nx,ny,0) as well as those components at the other faces of the simulation volume are just never updated?
If I set the BC in -x to PMC, then all currents with index nx=0 are zero and a time-update (regardless of the boundary condition) only updates "inner" voltages,U(.,nx>0<Nx,ny>0<Ny,nz<Nz),
where the indices Nx, Ny, Nz indicate the greatest indices in the respective direction?