Hi Steven, Hello meep users, I have been interested in the details of the timing of electric and magnetic sources in meep, since if one puts an electric and magnetic source at the same location, it is possible to make a source that emits only to one side. This can be useful sometimes.
However, it seems to me that the magnetic sources are evaluated one time step ahead of the electric ones: they are out of sync. If you give them the same src-time object, then the fields for the electric source come out later. Usually this small delay does not cause major problems, of course, since most simulations do not depend of the precise timing of the source, and one time step is supposed to be a small delay anyway. But if one tries to combine electric and magnetic sources, then the difference is important, and in any case, an extra delay is just not proper. To demonstrate the issue, I have tried to come up with a very simple example: looking directly at the electric and magnetic fields emitted by a pulsed source in empty space, in one dimension. In this case the solution to Maxwell’s equations is of course well known: for a current source j(t) in the origin, the electric field is E(z,t)= - (1/2) j(t-|z|), and the magnetic field is H(z,t)=E(z,t) sign(z). This simple analytical result facilitates a direct comparison with meep’s calculated fields. For definiteness, I have attached below a .ctl file that I used to obtain the meep fields, as well as a small matlab script to plot the results. Looking at the fields, it immediately becomes apparent that the sources are not currents j(t) (as the notation in the meep manual suggests), but rather polarizations p(t) (as Steven has pointed out in the discussion list sometime), with j(t)=d/dt p(t). The electric and magnetic fields from meep are exactly (anti)symmetric in z, for both types of source (E and H), with the signs as expected, and the magnitudes are in excellent agreement as well (but the timing is more delicate). The (anti)symmetry in z confirms that my understanding of the z coordinates is ok (the script obtains the z positions from the hdf file, and the time of the field snapshot from the file name). Looking at the timing of the fields, it appears that the H field lags the E field by half a time step (perhaps not so surprising for an FDTD calculation). A closer look at the source code in “dft.cpp” confirms the time ordering: the update routine “fields_chunk::update_dfts(double timeE, double timeH)” gets called in “fields::update_dfts()” as “update_dfts(time(), time() - 0.5 * dt);”, suggesting that the magnetic field is indeed lagging half a time step. For an H source, it appears that meep’s E field nicely matches the analytical expression, based on the time in the file name, and the H field nicely matches the analytical expression if we take the time half a time step earlier, as is normal for the Yee algorithm. However, for an E source, it appears that both fields are lagging one extra time step. The matlab script plots the E and H fields, with extra signs automatically added so all the amplitudes have the same sign, regardless of the type of source or the sign of z, so that all the curves overlap. The result is shown in “ehexample1.png”. A zoom in on the peak , in “ehexample2.png”, clearly shows the half time step delay for the H field. A comparison of the peak for an E vs. an H source (“ehexample2.png” vs. “ehexample3.png”, same axis scaling) clearly shows the extra time step delay for the E source (compare the peak positions, or the top axes of the two graphs). (The extra delay is taken into account in the analytical result, so the solid and dashed curves keep overlapping in the plot.) Taking a closer look at the source code, I think I am able to point out where the discrepancy arises. Here is an excerpt from ./src/step.cpp: calc_sources(time() - 0.5 * dt); // for H sources step_h(); if (!disable_sources) step_h_source(); calc_sources(time()); // for E sources step_d(); update_e_from_d(); update_from_e(); t += 1; update_dfts(); In step_h_source(), the field is updated using current*dt, where current(t)=((dipole(t+dt) - dipole(t)) / dt) (according to meep.hpp). Since t is time()-0.5*dt from calc_sources() above, the update current is based on dipole(time()+0.5*dt)-dipole(time()-0.5*dt), which is appropriate to update H from H(time()-0.5*dt) to H(time()+0.5*dt), and the H sources are fine. In contrast, in update_e_from_d.cpp, d_minus_p is updated using dipole(t), where t is still time(), from the second call to calc_sources() above. The update happens *after* step_h() and step_d(), i.e., the fields are already propagated to time()+dt. So presumably the update_e_from_d() should use sources evaluated at time()+dt, instead of at time(). I think this is the reason that the E and H fields for an E source are delayed one extra time step. What would be the best way to fix this? Is just replacing calc_sources(time()); // for E sources by calc_sources(time()+dt); // for E sources ok? Best regards, Mischa (See attached file: ehexample.ctl)(See attached file: ehexample.m)(See attached file: ehexample1.png)(See attached file: ehexample2.png)(See attached file: ehexample3.png)
ehexample.ctl
Description: Binary data
ehexample.m
Description: Binary data
<<attachment: ehexample1.png>>
<<attachment: ehexample2.png>>
<<attachment: ehexample3.png>>
_______________________________________________ meep-discuss mailing list [email protected] http://ab-initio.mit.edu/cgi-bin/mailman/listinfo/meep-discuss

