On Tuesday, February 08, 2011 10:00:01 am meep-discuss-request@ab-
initio.mit.edu wrote:
>
> I am writing my code in c++ and have trouble in trying to output field. I
> do not know how to set the simulation time and tell meep that field needs
> to be output at regular time steps, which is done in libctl using the
> following syntax
> 
> (run-until 200
>            (at-beginning output-epsilon)
>            (to-appended "ez" (at-every 0.6 output-efield-z)))
> 
> How would you code the above in c++ ?  I am quite new to c++, thus would
> really value if someone could help me with this.

Geeth, sorry you did not get an answer for a real Meep author, but this is how 
I managed to get this to work.  Hopefully more experienced users will chime in 
to further improve the solution, especially if I have any misunderstandings.

So the 
fields.step();
method does not ask for an update interval argument, which is what you want to 
provide (.6, in your example).  That is because FDTD algorithms have a formula 
to compute the timestep based on the grid resolution and source frequency.  So 
you cannot set the interval, but you can read it in the class variable:

fields.dt

I do not know that Meep can update the fields with any finer temporal 
resolution, nor that you ever should, because Nyquist is already satisfied, and 
Meep runs the fastest that way (I am educated guessing about this).  If you 
really do need finer temporal resolution, it would just be a normal time domain 
upsampling interpolation, or equivalently, Nyquist interpolation.  In either 
case, Meep is not involved in it.  I've written my code to just use fields.dt 
as the sample interval, and not tried to force it to anything else.

So the actual fields update is just like in the manual:

while (fields.time() < burnin)
     fields.step();

but you recognize that each update is exactly fields.dt long.  Normally, I want 
just a single update, so I just call

fields.step();

and I know my state is now fields.dt seconds later.

Oh, and the easy part of your question is how to read out the field.  After 
every timestep, iterate over the locations you want:

  for (size_t t = 0; t < H.dim[0]; t++) {
        fields.step();
        for (size_t i = 0; i < H.dim[1]; i++) {
            float x = volume.xmin() + xsize*i/(H.dim[1]-1);
            for (size_t j = 0; j < H.dim[2]; j++) {
                float y = volume.ymin() + ysize*j/(H.dim[2]-1);
                meep::vec loc(x,y);
                H[t][i][j][0] = fields.get_field(meep::Hx, loc).real();
                H[t][i][j][1] = fields.get_field(meep::Hy, loc).real();

Now the dim[0] stuff and the array indexing will depend on the array class you 
are using (here, I am using a boost::multi_array subclass for H that defines 
dim[]).  xsize and ysize are the meep::vol2d dimensions. The cool thing about 
this is that the loc(x,y) vectors  do *not* have to be on the grid!  They can 
be arbitrary locations wherever you want them, and Meep will perform the 
interpolation for you.

Hope that helps.  You will also need the Meep c++ manual to make complete 
sense of this  message.

John

_______________________________________________
meep-discuss mailing list
[email protected]
http://ab-initio.mit.edu/cgi-bin/mailman/listinfo/meep-discuss

Reply via email to