How to realize the change of refractive index with space and time in plugin material

fdtd
materialplugin

#1

I want to realize the change of refractive index with space and time in plugin material.Unfortunately,I have not found example about the refractive index disturbance along with the space in the Advanced material models (https://kb.lumerical.com/en/index.html?nanophotonics.html)
For example ,I wand to realize the disturbance in the refractive index by ε(x,t)=cos⁡(ωt+kx),and then I can return the function V/(U+cos⁡(ωt+kx)) in the .cpp.
And now I was very anxious to achieve this effect.


How to realize the change of refractive index with space and time in plugin material
#2

Hi @phd.wangbo,

The time variation of the permittivity can be included using the material plugin framework as in the step index perturbation example here. The problem is the spatial variation because the plugin framework does not provide access to the positions in the mesh where the field updates happen.

Would it be possible to decouple the spatial and time variation to have a permittivity of the form ε(x,t) = ε1(x) + ε2(t)? If this was possible then the spatial variation could be included in the base material for the plugin.

The other alternative is to take a step back and consider the effect that causes the permittivity modulation. Is it some sort of intensity-dependent refractive index? It might be possible to simulate the nonlinear process leading to the permittivity modulation instead of trying to include the effect through the modulated index.

Hope this helps!


#3

Thank you for your reply above!@fgomez
We regret that this model ε(x,t)=cos⁡(ωt+kx) cannot be achieved, because the spatial modulation is essential in our study, and there is no nonlinear effect on the refractive index change in our model. However, If we are possible to decouple the spatial and time variation to have a permittivity of the form ε(x,t) = ε1(x) + ε2(t),how can we implement the spatial variation in the base material? For example,the form of the permittivity modulation is that ε=cos⁡(wt)+cos⁡(kx),

For another question,we have written a set of codes in C++ about the time variation of the permittivity ,but we are not sure that this effect can be achieved .For example ,the permittivity variation is x=[n0+detalcos(wt)]^2-(n0)^2{n0 is the refractive of base material,detal is arbitrary constant we want to enter in the material database},and then we return the fuction V/(U+[n0+detalcos(wt)]^2-(n0)^2).However,we have a problem about the code we written below
const char* CosIndexMaterialPlugin::names[4] = {“delta”, “time_start”, “time_stop”, 0};
void CosIndexMaterialPlugin::initialize(const double** parameters, double dt)
{
for(int i=0; i<3; i++){
delta[i] = float(parameters[0][i]);
}

time_start = parameters[1][0];
time_stop = parameters[2][0];
time_dt = dt;

}
Is it necessary to carry out the for loop assignment for delta? And I don’t know what is meaning for the loop assignment for delta,but the step index perturbation example here have done.Now I’ll give you the code we written to see if there is a problem{n0=2.78 ,(n0)^2=7.7284 in the code}.Expecting your reply!(cosindex.h).txt (1.1 KB)
(cosindex.cpp).txt (1.5 KB)


#4

Hi @phd.wangbo,

Regarding the spatial variation of the index, you can use the Import object - Spatial (n,k) data method for the base material. You just need to create a text file (with the appropriate formatting, described in the link above) that contains the material index evaluated at different points in the structure.

For the time variation, the .cpp and .h files you provided are essentially correct. I just added some parameters for the variables omega and n0 so that you don’t have to recompile the material when you change these. In the step index plugin the parameter delta_eps is a vector (that is why you have the loop in the initialization) so that you can set different perturbations for each Cartesian axis. You can do the same for n0 and delta without any extra effort (if you don’t specify different values in the material properties, the same values will be used for all directions):

Parameters declared in cosindex_modFG.h:

double omega; /*new parameter*/
float n0 [3]; /*new parameters*/
float delta[3];
double time_start;
double time_stop;

static const char* names[6]; /*the dimension of this array must be the number of parameters +1*/

Initialization of parameters in cosindex_modFG.cpp:

void CosIndexMaterialPlugin ::initialize(const double** parameters, double dt)
{
    omega = parameters[0][0];
	
	for(int i=0; i<3; i++){
		n0[i] = float(parameters[1][i]);
		delta[i] = float(parameters[2][i]);
    }

    time_start = parameters[3][0];
    time_stop = parameters[4][0];
    time_dt = dt;

}

Field update in cosindex_modFG.cpp:

float CosIndexMaterialPlugin ::calculate(int axis, float U, float V, float E, float* storage)
{
    storage[0] += time_dt;
    bool change_index = (storage[0] > time_start) && (storage[0] < time_stop);
    return change_index ? V/(U + (n0[axis]+delta[axis]*cos(omega*storage[0]))*(n0[axis]+delta[axis]*cos(omega*storage[0])) - n0[axis]*n0[axis]) : V/U;
}

The perturbation will be turned on between time_start and time_stop. Note that instead of the if statement you can use the compact ternary operator ? : .

The modified source code is here: (cosindex_modFG_.h).txt (1.2 KB)
(cosindex_modFG.cpp).txt (1.4 KB)

Hope this helps!


#5

You have give an useful reply for me!
Thanks a lot


#6

HI @fgomez
I had found some problem about your code you had provided for me.
For one,[quote=“fgomez, post:4, topic:3205”]
omega = float(parameters[0]);
[/quote]

is it missing a symbol [0].I think that is omega=float(paramaters[0][0]);
another one,the (cosindex_modFG_.h).txt that you provide also have same problem.In the txt,the omega is a array that including 3 element,but the parameters[0] only provide one for the omega.Should be put the omega into the loop in the initialization?
Looking forward to your reply!


#7

Hi @phd.wangbo,

You are right! I made a mistake in both the .h and .cpp files. My intention was to have omega as a single parameter (not an array). In that case the variable declaration in cosindex_modFG.h should be

double omega; // declare single value omega

and the initialization in cosindex_modFG.cpp should be:

omega = parameters[0][0];

Alternatively, if you want to have an array of omega (one value for each Cartesian component) then you would need

float omega[3]; // declare array of omega

and

for(int i=0; i<3; i++){
    omega[i] = float(parameters[0][i]);
    n0[i] = float(parameters[1][i]);
    delta[i] = float(parameters[2][i]);
}

Sorry for the confusion and thanks for catching these bugs. I updated my previous post and the attached files to fix these issues.


#8

Which software program you used to generate the DLL file; Visual studio or Codeblocks or both are the same, I’m using codeblocks and after I generate the DLL file and move it to the bin of lumerical, I can’see that DLL file? anyhelp?


#9

Hi Ahmad,

Sorry for the wait. We normally generate the .dll files using Visual Studio as explained in this demo. However, in principle it should be possible to do it using other tools like Codeblocks, depending on how familiar you are with it.

You mentioned that you can’t see the .dll file when moving it to the bin folder. The .dll file should be moved to Lumerical\FDTD\bin\plugins\materials. If you can’t see the file in this folder after moving or copying it there, it is probably a permission problem. Is this the problem you are experiencing?


#10

It’s solved thanks a lot.