Hello,

I'm having another look at this problem, after having put it off for a
while.

The easy part was on the libctl side; in the specifications file I
modified dielectric materials to have "epsilon-tensor" and "scaled-
epsilon-tensor" properties.  If you provide no tensor when making your
dielectric, the material is assumed to be isotropic and the scaled
tensor will have the same dielectic constant along its diagonal.

If you want an anisotropic material, you can set epsilon to 1 and set
the epsilon-tensor to whatever you choose:

(define-class dielectric material-type
   (define-property epsilon no-default 'number)
   (define-property epsilon-tensor (matrix3x3 (vector3 1 0 0) (vector3 0 1 0) 
(vector3 0 0 1)) 'matrix3x3)
   (define-derived-property scaled-epsilon-tensor 'matrix3x3
     (lambda (object)
       (matrix3x3* (object-property-value object 'epsilon)
                    (object-property-value object 'epsilon-tensor))))
   (define-property polarizations '() (make-list-type 'polarizability))
   (define-property chi2 0 'number)
   (define-property chi3 0 'number)
)

Resulting in this behavior:

meep> (define a (make dielectric (epsilon 3)))
meep> (define b (make dielectric (epsilon 1) (epsilon-tensor (matrix3x3 
(vector3 4.8 0 0) (vector3 0 4.8 0) (vector3 0 0 5.2)))))
meep> a
((dielectric material-type) (chi3 . 0) (chi2 . 0) (polarizations) 
(epsilon-tensor . #(#(1 0 0) #(0 1 0) #(0 0 1))) (epsilon . 3) 
(scaled-epsilon-tensor . #(#(3 0 0) #(0 3 0) #(0 0 3))))
meep> b
((dielectric material-type) (chi3 . 0) (chi2 . 0) (polarizations) 
(epsilon-tensor . #(#(4.8 0 0) #(0 4.8 0) #(0 0 5.2))) (epsilon . 1) 
(scaled-epsilon-tensor . #(#(4.8 0 0) #(0 4.8 0) #(0 0 5.2))))


On the C side, things get trickier, and I'm a bit lost.  There are
several things I don't understand in the code:

1) structure_chunk::set_epsilon (specified in
anisotropic_averaging.cpp) is passed a material_function. That class
has one-liner methods specified in meep.hpp, (eps(), sigma(), chi3(),
and chi2()).

public:
   simple_material_function(double (*func)(const vec &)) { f = func; }

   virtual ~simple_material_function() {}

   virtual double eps(const vec &r) { return f(r); }
   virtual double sigma(const vec &r) { return f(r); }
   virtual double chi3(const vec &r) { return f(r); }
   virtual double chi2(const vec &r) { return f(r); }
};


I think when using the c++ interface, you define these functions yourself, like 
this:

double eps(const vec &p) {
         vec r = p - center;
         if (abs(r) < rad) return er;
         else return 1.0;
}

But how do these functions get informed or populated when running meep
via libctl?  More specifically, how can material_functions access the
scaled-epsilon-tensor (matrix3x3) above?

2) Should a new subclass of material_function be defined? In
simple_material_function, eps, sigma, chi3, chi2 are all doubles, so
you can use that template-esque code above.  Since the epsilon-tensor
is not a double, I should probably return a matrix3x3 struct (those
are typedef'ed in ctl.h, which I think meep.hpp is unaware of... ).

3) If I manage to set the inveps of structure_chunk, any subsequent
calls to set_epsilon() will clobber those values.  This means the
interface should set inveps only after set_epsilon has been called?

4) Is it possible to set inveps in a way which takes advantage of the
existing anisotropic averaging code (which also sets inveps)?

These aren't related to this problem, but I'm still curious:
5) What's an IVEC?
6) What's a yucky_val???

Best,
Matt







On Wed, 10 Oct 2007, Steven G. Johnson wrote:

> On Wed, 10 Oct 2007, matt wrote:
>> I'd like to follow up on these messages, where it was suggested that
>> hacks are possible for specifying anisotropic dielectrics.
>>
>> http://www.mail-archive.com/[email protected]/msg00779.html
>> http://www.mail-archive.com/[email protected]/msg00067.html
>>
>> Are these hacks documented somewhere?  If not, could anyone who
>> successfully got anisotropy working clue us in on how they achieved
>> this?
>
> Meep stores anisotropic dielectrics internally via the structure::inveps
> data structure (which stores a 3x3 matrix of 1/epsilon at each point, or
> rather the relevant row of that matrix at each Yee point).  However, there
> is currently no interface to specify this manually (it is only used for
> the subpixel averaging).  You would have to add a function to structure::
> to set it.
>
> Steven
>
> _______________________________________________
> meep-discuss mailing list
> [email protected]
> http://ab-initio.mit.edu/cgi-bin/mailman/listinfo/meep-discuss
>

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

Reply via email to