Merge lp:~emmanuel-lambert/python-meep/intec into lp:~nizamov-shawkat/python-meep/devel

Proposed by Emmanuel Lambert
Status: Merged
Merge reported by: Emmanuel Lambert
Merged at revision: not available
Proposed branch: lp:~emmanuel-lambert/python-meep/intec
Merge into: lp:~nizamov-shawkat/python-meep/devel
Diff against target: 22461 lines (+21840/-0)
106 files modified
AUTHORS (+2/-0)
COPYING (+674/-0)
COPYRIGHT (+17/-0)
README (+27/-0)
doc/html-sources/Makefile (+88/-0)
doc/html-sources/conf.py (+194/-0)
doc/html-sources/make.bat (+112/-0)
doc/html-sources/python_meep_documentation.txt (+1299/-0)
doc/html/.buildinfo (+4/-0)
doc/html/_sources/.svn/all-wcprops (+11/-0)
doc/html/_sources/.svn/entries (+62/-0)
doc/html/_sources/.svn/format (+1/-0)
doc/html/_sources/.svn/text-base/python_meep_documentation.txt.svn-base (+1293/-0)
doc/html/_sources/python_meep_documentation.txt (+1299/-0)
doc/html/_static/basic.css (+405/-0)
doc/html/_static/default.css (+210/-0)
doc/html/_static/doctools.js (+232/-0)
doc/html/_static/jquery.js (+32/-0)
doc/html/_static/pygments.css (+61/-0)
doc/html/_static/searchtools.js (+467/-0)
doc/html/genindex.html (+89/-0)
doc/html/objects.inv (+3/-0)
doc/html/python_meep_documentation.html (+1355/-0)
doc/html/search.html (+91/-0)
doc/html/searchindex.js (+1/-0)
make-mpi (+10/-0)
meep-common.py (+265/-0)
meep-site-init.py (+24/-0)
meep-site-init.py.intec (+40/-0)
meep-site-init.py.standard (+24/-0)
meep_common.i (+149/-0)
meep_mpi.i (+27/-0)
openmpi-bug.py (+17/-0)
samples/bent_waveguide/eps_class.hpp (+78/-0)
samples/bent_waveguide/eps_function.hpp (+55/-0)
samples/bent_waveguide/go (+11/-0)
samples/bent_waveguide/go-pictures (+31/-0)
samples/bent_waveguide/go_inline_class (+11/-0)
samples/bent_waveguide/go_inline_func (+11/-0)
samples/bent_waveguide/python_meep_bent_wg.py (+203/-0)
samples/bent_waveguide/python_meep_bent_wg_inline_class.py (+188/-0)
samples/bent_waveguide/python_meep_bent_wg_inline_function.py (+177/-0)
samples/circular_planewave_3d.py (+101/-0)
samples/use_averaging.py (+41/-0)
setup-mpi.py (+60/-0)
setup.py (+8/-0)
tests-intec/.svn/all-wcprops (+89/-0)
tests-intec/.svn/entries (+511/-0)
tests-intec/.svn/format (+1/-0)
tests-intec/.svn/prop-base/2D_convergence.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/bench.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/bragg_transmission.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/convergence_cyl_waveguide.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/cylindrical.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/flux.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/harmonics.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/known_results.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/one_dimensional.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/physical.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/pml.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/symmetry.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/three_d.py.svn-base (+5/-0)
tests-intec/.svn/prop-base/two_dimensional.py.svn-base (+5/-0)
tests-intec/.svn/text-base/2D_convergence.py.svn-base (+132/-0)
tests-intec/.svn/text-base/bench.py.svn-base (+280/-0)
tests-intec/.svn/text-base/bragg_transmission.py.svn-base (+219/-0)
tests-intec/.svn/text-base/convergence_cyl_waveguide.py.svn-base (+184/-0)
tests-intec/.svn/text-base/cylindrical.py.svn-base (+307/-0)
tests-intec/.svn/text-base/flux.py.svn-base (+320/-0)
tests-intec/.svn/text-base/harmonics.py.svn-base (+117/-0)
tests-intec/.svn/text-base/known_results.py.svn-base (+192/-0)
tests-intec/.svn/text-base/one_dimensional.py.svn-base (+156/-0)
tests-intec/.svn/text-base/physical.py.svn-base (+64/-0)
tests-intec/.svn/text-base/pml.py.svn-base (+209/-0)
tests-intec/.svn/text-base/symmetry.py.svn-base (+1059/-0)
tests-intec/.svn/text-base/three_d.py.svn-base (+240/-0)
tests-intec/.svn/text-base/two_dimensional.py.svn-base (+379/-0)
tests-intec/2D_convergence.py (+132/-0)
tests-intec/bench.py (+280/-0)
tests-intec/bragg_transmission.py (+219/-0)
tests-intec/convergence_cyl_waveguide.py (+183/-0)
tests-intec/cylindrical.py (+307/-0)
tests-intec/flux.py (+320/-0)
tests-intec/harmonics.py (+117/-0)
tests-intec/known_results.py (+192/-0)
tests-intec/one_dimensional.py (+156/-0)
tests-intec/physical.py (+64/-0)
tests-intec/pml.py (+209/-0)
tests-intec/symmetry.py (+1059/-0)
tests-intec/three_d.py (+240/-0)
tests-intec/two_dimensional.py (+379/-0)
tests/2D_convergence.py (+134/-0)
tests/bench.py (+282/-0)
tests/bragg_transmission.py (+221/-0)
tests/convergence_cyl_waveguide.py (+185/-0)
tests/cylindrical.py (+309/-0)
tests/flux.py (+321/-0)
tests/harmonics.py (+119/-0)
tests/known_results.py (+194/-0)
tests/one_dimensional.py (+158/-0)
tests/physical.py (+66/-0)
tests/pml.py (+211/-0)
tests/symmetry.py (+1059/-0)
tests/three_d.py (+242/-0)
tests/two_dimensional.py (+381/-0)
weave-bug.py (+12/-0)
To merge this branch: bzr merge lp:~emmanuel-lambert/python-meep/intec
Reviewer Review Type Date Requested Status
Nizamov Shawkat Approve
Review via email: mp+10791@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Emmanuel Lambert (emmanuel-lambert) wrote :

proposal for merge into Shawkat's branch

Revision history for this message
Nizamov Shawkat (nizamov-shawkat) :
review: Approve
8. By Emmanuel Lambert <email address hidden>

*Introduction of new class 'structure_eps_pml' that always defautls to EPS-averaging enabled (consistent with Scheme behaviour)
*Changes to the bent_waveguide sample to make it more consistent with the Scheme sample
*Conversion to meep-1.1.1

9. By Emmanuel Lambert <email address hidden>

file meep_common.i

10. By Emmanuel Lambert <email address hidden>

Declare EPS-functions through inline C-function or C++-class (improved performance).
Update of sources, sample and documentation.

11. By Emmanuel Lambert <email address hidden>

Examples for EPS-function through inline C or C++

12. By Emmanuel Lambert <email address hidden>

update of setup.py script

13. By Emmanuel Lambert <email address hidden>

changes in make and setup.py to support -I parameter

14. By Emmanuel Lambert <email address hidden>

deletion of .svn files

15. By Emmanuel Lambert <email address hidden>

changes in configuration files

16. By Emmanuel Lambert <email address hidden>

configuration files for MPI

17. By Emmanuel Lambert <email address hidden>

bugfix for MPI version

18. By Emmanuel Lambert <email address hidden>

various improvements; resolution of bug 447309

19. By Emmanuel Lambert <email address hidden>

sources of doc files

20. By Emmanuel Lambert <email address hidden>

sources of documentation files

21. By Emmanuel Lambert <email address hidden>

* callback function for source amplitude factor
* merge of NS code for custom source
* update of documentation, fix issues 457159+457156

22. By Emmanuel Lambert <email address hidden>

merging differences with NS branch - not yet completely functional and tested

23. By Emmanuel Lambert <email address hidden>

forgot to add meep-common.py

24. By Emmanuel Lambert <email address hidden>

removed a redundant file

25. By Emmanuel Lambert <email address hidden>

added 3 warnings at startup / complex double callback now working fine / implemented site-specific initialisations

26. By Emmanuel Lambert <email address hidden>

intermediate commit with update of unit tests (remaining: cylindrical, symmetry, three)

27. By Emmanuel Lambert <email address hidden>

v0.7beta - **all unit tests pass** -> MPI-version remains to be tested

28. By Emmanuel Lambert <email address hidden>

updates to setup script, more specifically for MPI

29. By Emmanuel Lambert <email address hidden>

minor update to bent waveguide sample

30. By Emmanuel Lambert <email address hidden>

further merging with NS / replacing tests dir with default tests and creating new 'tests-intec' subdir

31. By Emmanuel Lambert <email address hidden>

further merging with NS branch / update of tests subdir / added test-intec subdir

32. By Emmanuel Lambert <email address hidden>

reverted structure class to be in line with c++ core / imported extra circular_planewave example / fixed complex_time callback issue

33. By Emmanuel Lambert <email address hidden>

paths for incline C were hardcoded / replaced by environment variables

34. By Emmanuel Lambert <email address hidden>

small error in eps_class.hpp (inline C example)

35. By Emmanuel Lambert <email address hidden>

update of documentation - consistency with version 0.8

36. By Emmanuel Lambert <email address hidden>

minor changes in merging with NS branch

37. By Emmanuel Lambert <email address hidden>

minor change for merge

38. By Emmanuel Lambert <email address hidden>

added authors & GPL stuff

39. By Emmanuel Lambert <email address hidden>

merging

40. By Emmanuel Lambert <email address hidden>

version 1.0

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'AUTHORS'
--- AUTHORS 1970-01-01 00:00:00 +0000
+++ AUTHORS 2009-12-01 14:23:09 +0000
@@ -0,0 +1,2 @@
1Shawkat Nizamov <nizamov.shawkat@gmail.com>
2Emmanuel Lambert <Emmanuel.Lambert@intec.ugent.be>
03
=== renamed file 'AUTHORS' => 'AUTHORS.moved'
=== added file 'COPYING'
--- COPYING 1970-01-01 00:00:00 +0000
+++ COPYING 2009-12-01 14:23:09 +0000
@@ -0,0 +1,674 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 3, 29 June 2007
3
4 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5 Everyone is permitted to copy and distribute verbatim copies
6 of this license document, but changing it is not allowed.
7
8 Preamble
9
10 The GNU General Public License is a free, copyleft license for
11software and other kinds of works.
12
13 The licenses for most software and other practical works are designed
14to take away your freedom to share and change the works. By contrast,
15the GNU General Public License is intended to guarantee your freedom to
16share and change all versions of a program--to make sure it remains free
17software for all its users. We, the Free Software Foundation, use the
18GNU General Public License for most of our software; it applies also to
19any other work released this way by its authors. You can apply it to
20your programs, too.
21
22 When we speak of free software, we are referring to freedom, not
23price. Our General Public Licenses are designed to make sure that you
24have the freedom to distribute copies of free software (and charge for
25them if you wish), that you receive source code or can get it if you
26want it, that you can change the software or use pieces of it in new
27free programs, and that you know you can do these things.
28
29 To protect your rights, we need to prevent others from denying you
30these rights or asking you to surrender the rights. Therefore, you have
31certain responsibilities if you distribute copies of the software, or if
32you modify it: responsibilities to respect the freedom of others.
33
34 For example, if you distribute copies of such a program, whether
35gratis or for a fee, you must pass on to the recipients the same
36freedoms that you received. You must make sure that they, too, receive
37or can get the source code. And you must show them these terms so they
38know their rights.
39
40 Developers that use the GNU GPL protect your rights with two steps:
41(1) assert copyright on the software, and (2) offer you this License
42giving you legal permission to copy, distribute and/or modify it.
43
44 For the developers' and authors' protection, the GPL clearly explains
45that there is no warranty for this free software. For both users' and
46authors' sake, the GPL requires that modified versions be marked as
47changed, so that their problems will not be attributed erroneously to
48authors of previous versions.
49
50 Some devices are designed to deny users access to install or run
51modified versions of the software inside them, although the manufacturer
52can do so. This is fundamentally incompatible with the aim of
53protecting users' freedom to change the software. The systematic
54pattern of such abuse occurs in the area of products for individuals to
55use, which is precisely where it is most unacceptable. Therefore, we
56have designed this version of the GPL to prohibit the practice for those
57products. If such problems arise substantially in other domains, we
58stand ready to extend this provision to those domains in future versions
59of the GPL, as needed to protect the freedom of users.
60
61 Finally, every program is threatened constantly by software patents.
62States should not allow patents to restrict development and use of
63software on general-purpose computers, but in those that do, we wish to
64avoid the special danger that patents applied to a free program could
65make it effectively proprietary. To prevent this, the GPL assures that
66patents cannot be used to render the program non-free.
67
68 The precise terms and conditions for copying, distribution and
69modification follow.
70
71 TERMS AND CONDITIONS
72
73 0. Definitions.
74
75 "This License" refers to version 3 of the GNU General Public License.
76
77 "Copyright" also means copyright-like laws that apply to other kinds of
78works, such as semiconductor masks.
79
80 "The Program" refers to any copyrightable work licensed under this
81License. Each licensee is addressed as "you". "Licensees" and
82"recipients" may be individuals or organizations.
83
84 To "modify" a work means to copy from or adapt all or part of the work
85in a fashion requiring copyright permission, other than the making of an
86exact copy. The resulting work is called a "modified version" of the
87earlier work or a work "based on" the earlier work.
88
89 A "covered work" means either the unmodified Program or a work based
90on the Program.
91
92 To "propagate" a work means to do anything with it that, without
93permission, would make you directly or secondarily liable for
94infringement under applicable copyright law, except executing it on a
95computer or modifying a private copy. Propagation includes copying,
96distribution (with or without modification), making available to the
97public, and in some countries other activities as well.
98
99 To "convey" a work means any kind of propagation that enables other
100parties to make or receive copies. Mere interaction with a user through
101a computer network, with no transfer of a copy, is not conveying.
102
103 An interactive user interface displays "Appropriate Legal Notices"
104to the extent that it includes a convenient and prominently visible
105feature that (1) displays an appropriate copyright notice, and (2)
106tells the user that there is no warranty for the work (except to the
107extent that warranties are provided), that licensees may convey the
108work under this License, and how to view a copy of this License. If
109the interface presents a list of user commands or options, such as a
110menu, a prominent item in the list meets this criterion.
111
112 1. Source Code.
113
114 The "source code" for a work means the preferred form of the work
115for making modifications to it. "Object code" means any non-source
116form of a work.
117
118 A "Standard Interface" means an interface that either is an official
119standard defined by a recognized standards body, or, in the case of
120interfaces specified for a particular programming language, one that
121is widely used among developers working in that language.
122
123 The "System Libraries" of an executable work include anything, other
124than the work as a whole, that (a) is included in the normal form of
125packaging a Major Component, but which is not part of that Major
126Component, and (b) serves only to enable use of the work with that
127Major Component, or to implement a Standard Interface for which an
128implementation is available to the public in source code form. A
129"Major Component", in this context, means a major essential component
130(kernel, window system, and so on) of the specific operating system
131(if any) on which the executable work runs, or a compiler used to
132produce the work, or an object code interpreter used to run it.
133
134 The "Corresponding Source" for a work in object code form means all
135the source code needed to generate, install, and (for an executable
136work) run the object code and to modify the work, including scripts to
137control those activities. However, it does not include the work's
138System Libraries, or general-purpose tools or generally available free
139programs which are used unmodified in performing those activities but
140which are not part of the work. For example, Corresponding Source
141includes interface definition files associated with source files for
142the work, and the source code for shared libraries and dynamically
143linked subprograms that the work is specifically designed to require,
144such as by intimate data communication or control flow between those
145subprograms and other parts of the work.
146
147 The Corresponding Source need not include anything that users
148can regenerate automatically from other parts of the Corresponding
149Source.
150
151 The Corresponding Source for a work in source code form is that
152same work.
153
154 2. Basic Permissions.
155
156 All rights granted under this License are granted for the term of
157copyright on the Program, and are irrevocable provided the stated
158conditions are met. This License explicitly affirms your unlimited
159permission to run the unmodified Program. The output from running a
160covered work is covered by this License only if the output, given its
161content, constitutes a covered work. This License acknowledges your
162rights of fair use or other equivalent, as provided by copyright law.
163
164 You may make, run and propagate covered works that you do not
165convey, without conditions so long as your license otherwise remains
166in force. You may convey covered works to others for the sole purpose
167of having them make modifications exclusively for you, or provide you
168with facilities for running those works, provided that you comply with
169the terms of this License in conveying all material for which you do
170not control copyright. Those thus making or running the covered works
171for you must do so exclusively on your behalf, under your direction
172and control, on terms that prohibit them from making any copies of
173your copyrighted material outside their relationship with you.
174
175 Conveying under any other circumstances is permitted solely under
176the conditions stated below. Sublicensing is not allowed; section 10
177makes it unnecessary.
178
179 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180
181 No covered work shall be deemed part of an effective technological
182measure under any applicable law fulfilling obligations under article
18311 of the WIPO copyright treaty adopted on 20 December 1996, or
184similar laws prohibiting or restricting circumvention of such
185measures.
186
187 When you convey a covered work, you waive any legal power to forbid
188circumvention of technological measures to the extent such circumvention
189is effected by exercising rights under this License with respect to
190the covered work, and you disclaim any intention to limit operation or
191modification of the work as a means of enforcing, against the work's
192users, your or third parties' legal rights to forbid circumvention of
193technological measures.
194
195 4. Conveying Verbatim Copies.
196
197 You may convey verbatim copies of the Program's source code as you
198receive it, in any medium, provided that you conspicuously and
199appropriately publish on each copy an appropriate copyright notice;
200keep intact all notices stating that this License and any
201non-permissive terms added in accord with section 7 apply to the code;
202keep intact all notices of the absence of any warranty; and give all
203recipients a copy of this License along with the Program.
204
205 You may charge any price or no price for each copy that you convey,
206and you may offer support or warranty protection for a fee.
207
208 5. Conveying Modified Source Versions.
209
210 You may convey a work based on the Program, or the modifications to
211produce it from the Program, in the form of source code under the
212terms of section 4, provided that you also meet all of these conditions:
213
214 a) The work must carry prominent notices stating that you modified
215 it, and giving a relevant date.
216
217 b) The work must carry prominent notices stating that it is
218 released under this License and any conditions added under section
219 7. This requirement modifies the requirement in section 4 to
220 "keep intact all notices".
221
222 c) You must license the entire work, as a whole, under this
223 License to anyone who comes into possession of a copy. This
224 License will therefore apply, along with any applicable section 7
225 additional terms, to the whole of the work, and all its parts,
226 regardless of how they are packaged. This License gives no
227 permission to license the work in any other way, but it does not
228 invalidate such permission if you have separately received it.
229
230 d) If the work has interactive user interfaces, each must display
231 Appropriate Legal Notices; however, if the Program has interactive
232 interfaces that do not display Appropriate Legal Notices, your
233 work need not make them do so.
234
235 A compilation of a covered work with other separate and independent
236works, which are not by their nature extensions of the covered work,
237and which are not combined with it such as to form a larger program,
238in or on a volume of a storage or distribution medium, is called an
239"aggregate" if the compilation and its resulting copyright are not
240used to limit the access or legal rights of the compilation's users
241beyond what the individual works permit. Inclusion of a covered work
242in an aggregate does not cause this License to apply to the other
243parts of the aggregate.
244
245 6. Conveying Non-Source Forms.
246
247 You may convey a covered work in object code form under the terms
248of sections 4 and 5, provided that you also convey the
249machine-readable Corresponding Source under the terms of this License,
250in one of these ways:
251
252 a) Convey the object code in, or embodied in, a physical product
253 (including a physical distribution medium), accompanied by the
254 Corresponding Source fixed on a durable physical medium
255 customarily used for software interchange.
256
257 b) Convey the object code in, or embodied in, a physical product
258 (including a physical distribution medium), accompanied by a
259 written offer, valid for at least three years and valid for as
260 long as you offer spare parts or customer support for that product
261 model, to give anyone who possesses the object code either (1) a
262 copy of the Corresponding Source for all the software in the
263 product that is covered by this License, on a durable physical
264 medium customarily used for software interchange, for a price no
265 more than your reasonable cost of physically performing this
266 conveying of source, or (2) access to copy the
267 Corresponding Source from a network server at no charge.
268
269 c) Convey individual copies of the object code with a copy of the
270 written offer to provide the Corresponding Source. This
271 alternative is allowed only occasionally and noncommercially, and
272 only if you received the object code with such an offer, in accord
273 with subsection 6b.
274
275 d) Convey the object code by offering access from a designated
276 place (gratis or for a charge), and offer equivalent access to the
277 Corresponding Source in the same way through the same place at no
278 further charge. You need not require recipients to copy the
279 Corresponding Source along with the object code. If the place to
280 copy the object code is a network server, the Corresponding Source
281 may be on a different server (operated by you or a third party)
282 that supports equivalent copying facilities, provided you maintain
283 clear directions next to the object code saying where to find the
284 Corresponding Source. Regardless of what server hosts the
285 Corresponding Source, you remain obligated to ensure that it is
286 available for as long as needed to satisfy these requirements.
287
288 e) Convey the object code using peer-to-peer transmission, provided
289 you inform other peers where the object code and Corresponding
290 Source of the work are being offered to the general public at no
291 charge under subsection 6d.
292
293 A separable portion of the object code, whose source code is excluded
294from the Corresponding Source as a System Library, need not be
295included in conveying the object code work.
296
297 A "User Product" is either (1) a "consumer product", which means any
298tangible personal property which is normally used for personal, family,
299or household purposes, or (2) anything designed or sold for incorporation
300into a dwelling. In determining whether a product is a consumer product,
301doubtful cases shall be resolved in favor of coverage. For a particular
302product received by a particular user, "normally used" refers to a
303typical or common use of that class of product, regardless of the status
304of the particular user or of the way in which the particular user
305actually uses, or expects or is expected to use, the product. A product
306is a consumer product regardless of whether the product has substantial
307commercial, industrial or non-consumer uses, unless such uses represent
308the only significant mode of use of the product.
309
310 "Installation Information" for a User Product means any methods,
311procedures, authorization keys, or other information required to install
312and execute modified versions of a covered work in that User Product from
313a modified version of its Corresponding Source. The information must
314suffice to ensure that the continued functioning of the modified object
315code is in no case prevented or interfered with solely because
316modification has been made.
317
318 If you convey an object code work under this section in, or with, or
319specifically for use in, a User Product, and the conveying occurs as
320part of a transaction in which the right of possession and use of the
321User Product is transferred to the recipient in perpetuity or for a
322fixed term (regardless of how the transaction is characterized), the
323Corresponding Source conveyed under this section must be accompanied
324by the Installation Information. But this requirement does not apply
325if neither you nor any third party retains the ability to install
326modified object code on the User Product (for example, the work has
327been installed in ROM).
328
329 The requirement to provide Installation Information does not include a
330requirement to continue to provide support service, warranty, or updates
331for a work that has been modified or installed by the recipient, or for
332the User Product in which it has been modified or installed. Access to a
333network may be denied when the modification itself materially and
334adversely affects the operation of the network or violates the rules and
335protocols for communication across the network.
336
337 Corresponding Source conveyed, and Installation Information provided,
338in accord with this section must be in a format that is publicly
339documented (and with an implementation available to the public in
340source code form), and must require no special password or key for
341unpacking, reading or copying.
342
343 7. Additional Terms.
344
345 "Additional permissions" are terms that supplement the terms of this
346License by making exceptions from one or more of its conditions.
347Additional permissions that are applicable to the entire Program shall
348be treated as though they were included in this License, to the extent
349that they are valid under applicable law. If additional permissions
350apply only to part of the Program, that part may be used separately
351under those permissions, but the entire Program remains governed by
352this License without regard to the additional permissions.
353
354 When you convey a copy of a covered work, you may at your option
355remove any additional permissions from that copy, or from any part of
356it. (Additional permissions may be written to require their own
357removal in certain cases when you modify the work.) You may place
358additional permissions on material, added by you to a covered work,
359for which you have or can give appropriate copyright permission.
360
361 Notwithstanding any other provision of this License, for material you
362add to a covered work, you may (if authorized by the copyright holders of
363that material) supplement the terms of this License with terms:
364
365 a) Disclaiming warranty or limiting liability differently from the
366 terms of sections 15 and 16 of this License; or
367
368 b) Requiring preservation of specified reasonable legal notices or
369 author attributions in that material or in the Appropriate Legal
370 Notices displayed by works containing it; or
371
372 c) Prohibiting misrepresentation of the origin of that material, or
373 requiring that modified versions of such material be marked in
374 reasonable ways as different from the original version; or
375
376 d) Limiting the use for publicity purposes of names of licensors or
377 authors of the material; or
378
379 e) Declining to grant rights under trademark law for use of some
380 trade names, trademarks, or service marks; or
381
382 f) Requiring indemnification of licensors and authors of that
383 material by anyone who conveys the material (or modified versions of
384 it) with contractual assumptions of liability to the recipient, for
385 any liability that these contractual assumptions directly impose on
386 those licensors and authors.
387
388 All other non-permissive additional terms are considered "further
389restrictions" within the meaning of section 10. If the Program as you
390received it, or any part of it, contains a notice stating that it is
391governed by this License along with a term that is a further
392restriction, you may remove that term. If a license document contains
393a further restriction but permits relicensing or conveying under this
394License, you may add to a covered work material governed by the terms
395of that license document, provided that the further restriction does
396not survive such relicensing or conveying.
397
398 If you add terms to a covered work in accord with this section, you
399must place, in the relevant source files, a statement of the
400additional terms that apply to those files, or a notice indicating
401where to find the applicable terms.
402
403 Additional terms, permissive or non-permissive, may be stated in the
404form of a separately written license, or stated as exceptions;
405the above requirements apply either way.
406
407 8. Termination.
408
409 You may not propagate or modify a covered work except as expressly
410provided under this License. Any attempt otherwise to propagate or
411modify it is void, and will automatically terminate your rights under
412this License (including any patent licenses granted under the third
413paragraph of section 11).
414
415 However, if you cease all violation of this License, then your
416license from a particular copyright holder is reinstated (a)
417provisionally, unless and until the copyright holder explicitly and
418finally terminates your license, and (b) permanently, if the copyright
419holder fails to notify you of the violation by some reasonable means
420prior to 60 days after the cessation.
421
422 Moreover, your license from a particular copyright holder is
423reinstated permanently if the copyright holder notifies you of the
424violation by some reasonable means, this is the first time you have
425received notice of violation of this License (for any work) from that
426copyright holder, and you cure the violation prior to 30 days after
427your receipt of the notice.
428
429 Termination of your rights under this section does not terminate the
430licenses of parties who have received copies or rights from you under
431this License. If your rights have been terminated and not permanently
432reinstated, you do not qualify to receive new licenses for the same
433material under section 10.
434
435 9. Acceptance Not Required for Having Copies.
436
437 You are not required to accept this License in order to receive or
438run a copy of the Program. Ancillary propagation of a covered work
439occurring solely as a consequence of using peer-to-peer transmission
440to receive a copy likewise does not require acceptance. However,
441nothing other than this License grants you permission to propagate or
442modify any covered work. These actions infringe copyright if you do
443not accept this License. Therefore, by modifying or propagating a
444covered work, you indicate your acceptance of this License to do so.
445
446 10. Automatic Licensing of Downstream Recipients.
447
448 Each time you convey a covered work, the recipient automatically
449receives a license from the original licensors, to run, modify and
450propagate that work, subject to this License. You are not responsible
451for enforcing compliance by third parties with this License.
452
453 An "entity transaction" is a transaction transferring control of an
454organization, or substantially all assets of one, or subdividing an
455organization, or merging organizations. If propagation of a covered
456work results from an entity transaction, each party to that
457transaction who receives a copy of the work also receives whatever
458licenses to the work the party's predecessor in interest had or could
459give under the previous paragraph, plus a right to possession of the
460Corresponding Source of the work from the predecessor in interest, if
461the predecessor has it or can get it with reasonable efforts.
462
463 You may not impose any further restrictions on the exercise of the
464rights granted or affirmed under this License. For example, you may
465not impose a license fee, royalty, or other charge for exercise of
466rights granted under this License, and you may not initiate litigation
467(including a cross-claim or counterclaim in a lawsuit) alleging that
468any patent claim is infringed by making, using, selling, offering for
469sale, or importing the Program or any portion of it.
470
471 11. Patents.
472
473 A "contributor" is a copyright holder who authorizes use under this
474License of the Program or a work on which the Program is based. The
475work thus licensed is called the contributor's "contributor version".
476
477 A contributor's "essential patent claims" are all patent claims
478owned or controlled by the contributor, whether already acquired or
479hereafter acquired, that would be infringed by some manner, permitted
480by this License, of making, using, or selling its contributor version,
481but do not include claims that would be infringed only as a
482consequence of further modification of the contributor version. For
483purposes of this definition, "control" includes the right to grant
484patent sublicenses in a manner consistent with the requirements of
485this License.
486
487 Each contributor grants you a non-exclusive, worldwide, royalty-free
488patent license under the contributor's essential patent claims, to
489make, use, sell, offer for sale, import and otherwise run, modify and
490propagate the contents of its contributor version.
491
492 In the following three paragraphs, a "patent license" is any express
493agreement or commitment, however denominated, not to enforce a patent
494(such as an express permission to practice a patent or covenant not to
495sue for patent infringement). To "grant" such a patent license to a
496party means to make such an agreement or commitment not to enforce a
497patent against the party.
498
499 If you convey a covered work, knowingly relying on a patent license,
500and the Corresponding Source of the work is not available for anyone
501to copy, free of charge and under the terms of this License, through a
502publicly available network server or other readily accessible means,
503then you must either (1) cause the Corresponding Source to be so
504available, or (2) arrange to deprive yourself of the benefit of the
505patent license for this particular work, or (3) arrange, in a manner
506consistent with the requirements of this License, to extend the patent
507license to downstream recipients. "Knowingly relying" means you have
508actual knowledge that, but for the patent license, your conveying the
509covered work in a country, or your recipient's use of the covered work
510in a country, would infringe one or more identifiable patents in that
511country that you have reason to believe are valid.
512
513 If, pursuant to or in connection with a single transaction or
514arrangement, you convey, or propagate by procuring conveyance of, a
515covered work, and grant a patent license to some of the parties
516receiving the covered work authorizing them to use, propagate, modify
517or convey a specific copy of the covered work, then the patent license
518you grant is automatically extended to all recipients of the covered
519work and works based on it.
520
521 A patent license is "discriminatory" if it does not include within
522the scope of its coverage, prohibits the exercise of, or is
523conditioned on the non-exercise of one or more of the rights that are
524specifically granted under this License. You may not convey a covered
525work if you are a party to an arrangement with a third party that is
526in the business of distributing software, under which you make payment
527to the third party based on the extent of your activity of conveying
528the work, and under which the third party grants, to any of the
529parties who would receive the covered work from you, a discriminatory
530patent license (a) in connection with copies of the covered work
531conveyed by you (or copies made from those copies), or (b) primarily
532for and in connection with specific products or compilations that
533contain the covered work, unless you entered into that arrangement,
534or that patent license was granted, prior to 28 March 2007.
535
536 Nothing in this License shall be construed as excluding or limiting
537any implied license or other defenses to infringement that may
538otherwise be available to you under applicable patent law.
539
540 12. No Surrender of Others' Freedom.
541
542 If conditions are imposed on you (whether by court order, agreement or
543otherwise) that contradict the conditions of this License, they do not
544excuse you from the conditions of this License. If you cannot convey a
545covered work so as to satisfy simultaneously your obligations under this
546License and any other pertinent obligations, then as a consequence you may
547not convey it at all. For example, if you agree to terms that obligate you
548to collect a royalty for further conveying from those to whom you convey
549the Program, the only way you could satisfy both those terms and this
550License would be to refrain entirely from conveying the Program.
551
552 13. Use with the GNU Affero General Public License.
553
554 Notwithstanding any other provision of this License, you have
555permission to link or combine any covered work with a work licensed
556under version 3 of the GNU Affero General Public License into a single
557combined work, and to convey the resulting work. The terms of this
558License will continue to apply to the part which is the covered work,
559but the special requirements of the GNU Affero General Public License,
560section 13, concerning interaction through a network will apply to the
561combination as such.
562
563 14. Revised Versions of this License.
564
565 The Free Software Foundation may publish revised and/or new versions of
566the GNU General Public License from time to time. Such new versions will
567be similar in spirit to the present version, but may differ in detail to
568address new problems or concerns.
569
570 Each version is given a distinguishing version number. If the
571Program specifies that a certain numbered version of the GNU General
572Public License "or any later version" applies to it, you have the
573option of following the terms and conditions either of that numbered
574version or of any later version published by the Free Software
575Foundation. If the Program does not specify a version number of the
576GNU General Public License, you may choose any version ever published
577by the Free Software Foundation.
578
579 If the Program specifies that a proxy can decide which future
580versions of the GNU General Public License can be used, that proxy's
581public statement of acceptance of a version permanently authorizes you
582to choose that version for the Program.
583
584 Later license versions may give you additional or different
585permissions. However, no additional obligations are imposed on any
586author or copyright holder as a result of your choosing to follow a
587later version.
588
589 15. Disclaimer of Warranty.
590
591 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599
600 16. Limitation of Liability.
601
602 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610SUCH DAMAGES.
611
612 17. Interpretation of Sections 15 and 16.
613
614 If the disclaimer of warranty and limitation of liability provided
615above cannot be given local legal effect according to their terms,
616reviewing courts shall apply local law that most closely approximates
617an absolute waiver of all civil liability in connection with the
618Program, unless a warranty or assumption of liability accompanies a
619copy of the Program in return for a fee.
620
621 END OF TERMS AND CONDITIONS
622
623 How to Apply These Terms to Your New Programs
624
625 If you develop a new program, and you want it to be of the greatest
626possible use to the public, the best way to achieve this is to make it
627free software which everyone can redistribute and change under these terms.
628
629 To do so, attach the following notices to the program. It is safest
630to attach them to the start of each source file to most effectively
631state the exclusion of warranty; and each file should have at least
632the "copyright" line and a pointer to where the full notice is found.
633
634 <one line to give the program's name and a brief idea of what it does.>
635 Copyright (C) <year> <name of author>
636
637 This program is free software: you can redistribute it and/or modify
638 it under the terms of the GNU General Public License as published by
639 the Free Software Foundation, either version 3 of the License, or
640 (at your option) any later version.
641
642 This program is distributed in the hope that it will be useful,
643 but WITHOUT ANY WARRANTY; without even the implied warranty of
644 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 GNU General Public License for more details.
646
647 You should have received a copy of the GNU General Public License
648 along with this program. If not, see <http://www.gnu.org/licenses/>.
649
650Also add information on how to contact you by electronic and paper mail.
651
652 If the program does terminal interaction, make it output a short
653notice like this when it starts in an interactive mode:
654
655 <program> Copyright (C) <year> <name of author>
656 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 This is free software, and you are welcome to redistribute it
658 under certain conditions; type `show c' for details.
659
660The hypothetical commands `show w' and `show c' should show the appropriate
661parts of the General Public License. Of course, your program's commands
662might be different; for a GUI interface, you would use an "about box".
663
664 You should also get your employer (if you work as a programmer) or school,
665if any, to sign a "copyright disclaimer" for the program, if necessary.
666For more information on this, and how to apply and follow the GNU GPL, see
667<http://www.gnu.org/licenses/>.
668
669 The GNU General Public License does not permit incorporating your program
670into proprietary programs. If your program is a subroutine library, you
671may consider it more useful to permit linking proprietary applications with
672the library. If this is what you want to do, use the GNU Lesser General
673Public License instead of this License. But first, please read
674<http://www.gnu.org/philosophy/why-not-lgpl.html>.
0675
=== renamed file 'COPYING' => 'COPYING.moved'
=== added file 'COPYRIGHT'
--- COPYRIGHT 1970-01-01 00:00:00 +0000
+++ COPYRIGHT 2009-12-01 14:23:09 +0000
@@ -0,0 +1,17 @@
1/* Copyright (C) 2008-2009 MSU, Phys, Group of Nanophotonics & Metamaterials
2 * Copyright (C) 2009 Universiteit Gent - INTEC - IMEC
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
018
=== renamed file 'COPYRIGHT' => 'COPYRIGHT.moved'
=== added file 'README'
--- README 1970-01-01 00:00:00 +0000
+++ README 2009-12-01 14:23:09 +0000
@@ -0,0 +1,27 @@
1Meep (or MEEP) is a free finite-difference time-domain (FDTD)
2simulation software package developed at MIT to model electromagnetic
3systems. You can download Meep and learn more about it at the Meep
4home page:
5
6 http://ab-initio.mit.edu/meep/
7
8The Meep home page also links to a meep-discuss mailing list for
9discussions about Meep and FDTD simulations, and a meep-announce
10mailing list for announcements of Meep releases.
11
12Python-meep is a wrapper around libmeep. It allows the scripting of
13simulation with meep using Python.
14
15Prerequisites for installation:
16 - libmeep (or libmeep-mpi) version 1.1.1
17 - mpi support (if used) - tested with OpenMPI version 1.3.3
18 - swig version 1.3.40
19 - gcc/g++ (required by swig)
20 - numpy, scipy and company
21
22There is a mailinglist available for Python-meep users :
23 python-meep@lists.launchpad.net
24
25A tutorial on how to write Python-meep scripts is available in the doc/html subdirectory:
26 python_meep_documentation.html
27
028
=== renamed file 'README' => 'README.moved'
=== added directory 'doc'
=== renamed directory 'doc' => 'doc.moved'
=== added directory 'doc/html'
=== added directory 'doc/html-sources'
=== added file 'doc/html-sources/Makefile'
--- doc/html-sources/Makefile 1970-01-01 00:00:00 +0000
+++ doc/html-sources/Makefile 2009-12-01 14:23:10 +0000
@@ -0,0 +1,88 @@
1# Makefile for Sphinx documentation
2#
3
4# You can set these variables from the command line.
5SPHINXOPTS =
6SPHINXBUILD = sphinx-build
7PAPER =
8
9# Internal variables.
10PAPEROPT_a4 = -D latex_paper_size=a4
11PAPEROPT_letter = -D latex_paper_size=letter
12ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
13
14.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
15
16help:
17 @echo "Please use \`make <target>' where <target> is one of"
18 @echo " html to make standalone HTML files"
19 @echo " dirhtml to make HTML files named index.html in directories"
20 @echo " pickle to make pickle files"
21 @echo " json to make JSON files"
22 @echo " htmlhelp to make HTML files and a HTML help project"
23 @echo " qthelp to make HTML files and a qthelp project"
24 @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
25 @echo " changes to make an overview of all changed/added/deprecated items"
26 @echo " linkcheck to check all external links for integrity"
27 @echo " doctest to run all doctests embedded in the documentation (if enabled)"
28
29clean:
30 -rm -rf _build/*
31
32html:
33 $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
34 @echo
35 @echo "Build finished. The HTML pages are in _build/html."
36
37dirhtml:
38 $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml
39 @echo
40 @echo "Build finished. The HTML pages are in _build/dirhtml."
41
42pickle:
43 $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
44 @echo
45 @echo "Build finished; now you can process the pickle files."
46
47json:
48 $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
49 @echo
50 @echo "Build finished; now you can process the JSON files."
51
52htmlhelp:
53 $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
54 @echo
55 @echo "Build finished; now you can run HTML Help Workshop with the" \
56 ".hhp project file in _build/htmlhelp."
57
58qthelp:
59 $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp
60 @echo
61 @echo "Build finished; now you can run "qcollectiongenerator" with the" \
62 ".qhcp project file in _build/qthelp, like this:"
63 @echo "# qcollectiongenerator _build/qthelp/python-meep-doc.qhcp"
64 @echo "To view the help file:"
65 @echo "# assistant -collectionFile _build/qthelp/python-meep-doc.qhc"
66
67latex:
68 $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
69 @echo
70 @echo "Build finished; the LaTeX files are in _build/latex."
71 @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
72 "run these through (pdf)latex."
73
74changes:
75 $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
76 @echo
77 @echo "The overview file is in _build/changes."
78
79linkcheck:
80 $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
81 @echo
82 @echo "Link check complete; look for any errors in the above output " \
83 "or in _build/linkcheck/output.txt."
84
85doctest:
86 $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest
87 @echo "Testing of doctests in the sources finished, look at the " \
88 "results in _build/doctest/output.txt."
089
=== added file 'doc/html-sources/conf.py'
--- doc/html-sources/conf.py 1970-01-01 00:00:00 +0000
+++ doc/html-sources/conf.py 2009-12-01 14:23:10 +0000
@@ -0,0 +1,194 @@
1# -*- coding: utf-8 -*-
2#
3# python-meep-doc documentation build configuration file, created by
4# sphinx-quickstart on Fri Aug 21 10:42:04 2009.
5#
6# This file is execfile()d with the current directory set to its containing dir.
7#
8# Note that not all possible configuration values are present in this
9# autogenerated file.
10#
11# All configuration values have a default; values that are commented out
12# serve to show the default.
13
14import sys, os
15
16# If extensions (or modules to document with autodoc) are in another directory,
17# add these directories to sys.path here. If the directory is relative to the
18# documentation root, use os.path.abspath to make it absolute, like shown here.
19#sys.path.append(os.path.abspath('.'))
20
21# -- General configuration -----------------------------------------------------
22
23# Add any Sphinx extension module names here, as strings. They can be extensions
24# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
25extensions = []
26
27# Add any paths that contain templates here, relative to this directory.
28templates_path = ['_templates']
29
30# The suffix of source filenames.
31source_suffix = '.txt'
32
33# The encoding of source files.
34#source_encoding = 'utf-8'
35
36# The master toctree document.
37master_doc = 'python_meep_documentation'
38
39# General information about the project.
40project = u'python-meep-doc'
41copyright = u'2009, Emmanuel.Lambert@intec.ugent.be'
42
43# The version info for the project you're documenting, acts as replacement for
44# |version| and |release|, also used in various other places throughout the
45# built documents.
46#
47# The short X.Y version.
48version = '0.1'
49# The full version, including alpha/beta/rc tags.
50release = '0.1'
51
52# The language for content autogenerated by Sphinx. Refer to documentation
53# for a list of supported languages.
54#language = None
55
56# There are two options for replacing |today|: either, you set today to some
57# non-false value, then it is used:
58#today = ''
59# Else, today_fmt is used as the format for a strftime call.
60#today_fmt = '%B %d, %Y'
61
62# List of documents that shouldn't be included in the build.
63#unused_docs = []
64
65# List of directories, relative to source directory, that shouldn't be searched
66# for source files.
67exclude_trees = ['_build']
68
69# The reST default role (used for this markup: `text`) to use for all documents.
70#default_role = None
71
72# If true, '()' will be appended to :func: etc. cross-reference text.
73#add_function_parentheses = True
74
75# If true, the current module name will be prepended to all description
76# unit titles (such as .. function::).
77#add_module_names = True
78
79# If true, sectionauthor and moduleauthor directives will be shown in the
80# output. They are ignored by default.
81#show_authors = False
82
83# The name of the Pygments (syntax highlighting) style to use.
84pygments_style = 'sphinx'
85
86# A list of ignored prefixes for module index sorting.
87#modindex_common_prefix = []
88
89
90# -- Options for HTML output ---------------------------------------------------
91
92# The theme to use for HTML and HTML Help pages. Major themes that come with
93# Sphinx are currently 'default' and 'sphinxdoc'.
94html_theme = 'default'
95
96# Theme options are theme-specific and customize the look and feel of a theme
97# further. For a list of options available for each theme, see the
98# documentation.
99#html_theme_options = {}
100
101# Add any paths that contain custom themes here, relative to this directory.
102#html_theme_path = []
103
104# The name for this set of Sphinx documents. If None, it defaults to
105# "<project> v<release> documentation".
106#html_title = None
107
108# A shorter title for the navigation bar. Default is the same as html_title.
109#html_short_title = None
110
111# The name of an image file (relative to this directory) to place at the top
112# of the sidebar.
113#html_logo = None
114
115# The name of an image file (within the static path) to use as favicon of the
116# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
117# pixels large.
118#html_favicon = None
119
120# Add any paths that contain custom static files (such as style sheets) here,
121# relative to this directory. They are copied after the builtin static files,
122# so a file named "default.css" will overwrite the builtin "default.css".
123html_static_path = ['_static']
124
125# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
126# using the given strftime format.
127#html_last_updated_fmt = '%b %d, %Y'
128
129# If true, SmartyPants will be used to convert quotes and dashes to
130# typographically correct entities.
131#html_use_smartypants = True
132
133# Custom sidebar templates, maps document names to template names.
134#html_sidebars = {}
135
136# Additional templates that should be rendered to pages, maps page names to
137# template names.
138#html_additional_pages = {}
139
140# If false, no module index is generated.
141#html_use_modindex = True
142
143# If false, no index is generated.
144#html_use_index = True
145
146# If true, the index is split into individual pages for each letter.
147#html_split_index = False
148
149# If true, links to the reST sources are added to the pages.
150#html_show_sourcelink = True
151
152# If true, an OpenSearch description file will be output, and all pages will
153# contain a <link> tag referring to it. The value of this option must be the
154# base URL from which the finished HTML is served.
155#html_use_opensearch = ''
156
157# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
158#html_file_suffix = ''
159
160# Output file base name for HTML help builder.
161htmlhelp_basename = 'python-meep-docdoc'
162
163
164# -- Options for LaTeX output --------------------------------------------------
165
166# The paper size ('letter' or 'a4').
167#latex_paper_size = 'letter'
168
169# The font size ('10pt', '11pt' or '12pt').
170#latex_font_size = '10pt'
171
172# Grouping the document tree into LaTeX files. List of tuples
173# (source start file, target name, title, author, documentclass [howto/manual]).
174latex_documents = [
175 ('python_meep_documentation', 'python-meep-doc.tex', u'python-meep-doc Documentation',
176 u'Emmanuel.Lambert@intec.ugent.be', 'manual'),
177]
178
179# The name of an image file (relative to this directory) to place at the top of
180# the title page.
181#latex_logo = None
182
183# For "manual" documents, if this is true, then toplevel headings are parts,
184# not chapters.
185#latex_use_parts = False
186
187# Additional stuff for the LaTeX preamble.
188#latex_preamble = ''
189
190# Documents to append as an appendix to all manuals.
191#latex_appendices = []
192
193# If false, no module index is generated.
194#latex_use_modindex = True
0195
=== added directory 'doc/html-sources/images'
=== added file 'doc/html-sources/images/bentwgB.gif'
1Binary files doc/html-sources/images/bentwgB.gif 1970-01-01 00:00:00 +0000 and doc/html-sources/images/bentwgB.gif 2009-12-01 14:23:10 +0000 differ196Binary files doc/html-sources/images/bentwgB.gif 1970-01-01 00:00:00 +0000 and doc/html-sources/images/bentwgB.gif 2009-12-01 14:23:10 +0000 differ
=== added file 'doc/html-sources/images/bentwgNB.gif'
2Binary files doc/html-sources/images/bentwgNB.gif 1970-01-01 00:00:00 +0000 and doc/html-sources/images/bentwgNB.gif 2009-12-01 14:23:10 +0000 differ197Binary files doc/html-sources/images/bentwgNB.gif 1970-01-01 00:00:00 +0000 and doc/html-sources/images/bentwgNB.gif 2009-12-01 14:23:10 +0000 differ
=== added file 'doc/html-sources/images/fluxes.png'
3Binary files doc/html-sources/images/fluxes.png 1970-01-01 00:00:00 +0000 and doc/html-sources/images/fluxes.png 2009-12-01 14:23:10 +0000 differ198Binary files doc/html-sources/images/fluxes.png 1970-01-01 00:00:00 +0000 and doc/html-sources/images/fluxes.png 2009-12-01 14:23:10 +0000 differ
=== added file 'doc/html-sources/make.bat'
--- doc/html-sources/make.bat 1970-01-01 00:00:00 +0000
+++ doc/html-sources/make.bat 2009-12-01 14:23:10 +0000
@@ -0,0 +1,112 @@
1@ECHO OFF
2
3REM Command file for Sphinx documentation
4
5set SPHINXBUILD=sphinx-build
6set ALLSPHINXOPTS=-d _build/doctrees %SPHINXOPTS% .
7if NOT "%PAPER%" == "" (
8 set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
9)
10
11if "%1" == "" goto help
12
13if "%1" == "help" (
14 :help
15 echo.Please use `make ^<target^>` where ^<target^> is one of
16 echo. html to make standalone HTML files
17 echo. dirhtml to make HTML files named index.html in directories
18 echo. pickle to make pickle files
19 echo. json to make JSON files
20 echo. htmlhelp to make HTML files and a HTML help project
21 echo. qthelp to make HTML files and a qthelp project
22 echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
23 echo. changes to make an overview over all changed/added/deprecated items
24 echo. linkcheck to check all external links for integrity
25 echo. doctest to run all doctests embedded in the documentation if enabled
26 goto end
27)
28
29if "%1" == "clean" (
30 for /d %%i in (_build\*) do rmdir /q /s %%i
31 del /q /s _build\*
32 goto end
33)
34
35if "%1" == "html" (
36 %SPHINXBUILD% -b html %ALLSPHINXOPTS% _build/html
37 echo.
38 echo.Build finished. The HTML pages are in _build/html.
39 goto end
40)
41
42if "%1" == "dirhtml" (
43 %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% _build/dirhtml
44 echo.
45 echo.Build finished. The HTML pages are in _build/dirhtml.
46 goto end
47)
48
49if "%1" == "pickle" (
50 %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% _build/pickle
51 echo.
52 echo.Build finished; now you can process the pickle files.
53 goto end
54)
55
56if "%1" == "json" (
57 %SPHINXBUILD% -b json %ALLSPHINXOPTS% _build/json
58 echo.
59 echo.Build finished; now you can process the JSON files.
60 goto end
61)
62
63if "%1" == "htmlhelp" (
64 %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% _build/htmlhelp
65 echo.
66 echo.Build finished; now you can run HTML Help Workshop with the ^
67.hhp project file in _build/htmlhelp.
68 goto end
69)
70
71if "%1" == "qthelp" (
72 %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% _build/qthelp
73 echo.
74 echo.Build finished; now you can run "qcollectiongenerator" with the ^
75.qhcp project file in _build/qthelp, like this:
76 echo.^> qcollectiongenerator _build\qthelp\python-meep-doc.qhcp
77 echo.To view the help file:
78 echo.^> assistant -collectionFile _build\qthelp\python-meep-doc.ghc
79 goto end
80)
81
82if "%1" == "latex" (
83 %SPHINXBUILD% -b latex %ALLSPHINXOPTS% _build/latex
84 echo.
85 echo.Build finished; the LaTeX files are in _build/latex.
86 goto end
87)
88
89if "%1" == "changes" (
90 %SPHINXBUILD% -b changes %ALLSPHINXOPTS% _build/changes
91 echo.
92 echo.The overview file is in _build/changes.
93 goto end
94)
95
96if "%1" == "linkcheck" (
97 %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% _build/linkcheck
98 echo.
99 echo.Link check complete; look for any errors in the above output ^
100or in _build/linkcheck/output.txt.
101 goto end
102)
103
104if "%1" == "doctest" (
105 %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% _build/doctest
106 echo.
107 echo.Testing of doctests in the sources finished, look at the ^
108results in _build/doctest/output.txt.
109 goto end
110)
111
112:end
0113
=== added file 'doc/html-sources/python_meep_documentation.txt'
--- doc/html-sources/python_meep_documentation.txt 1970-01-01 00:00:00 +0000
+++ doc/html-sources/python_meep_documentation.txt 2009-12-01 14:23:10 +0000
@@ -0,0 +1,1299 @@
1PYTHON-MEEP BINDING DOCUMENTATION
2====================================
3
4Primary author of this documentation : EL : Emmanuel.Lambert@intec.ugent.be
5
6Document history :
7
8::
9
10 * EL-19/20/21-08-2009 : document creation
11 * EL-24-08-2009 : small improvements & clarifications.
12 * EL-25/26-08-2009 : sections 7 & 8 were added.
13 * EL-03-04/09/2009 :
14 -class "structure_eps_pml" (removed again in v0.8).
15 -port to Meep 1.1.1 (class 'volume' was renamed to 'grid_volume' and class 'geometric_volume' to 'volume'
16 -minor changes in the bent waveguide sample, to make it more consistent with the Scheme version
17 * EL-07-08/09/2009 : sections 3.2, 8.2, 8.3 : defining a material function with inline C/C++
18 * EL-10/09/2009 : additions for MPI mode (multiprocessor)
19 * EL-21/10/2009 : amplitude factor callback function
20 * EL-22/10/2009 : keyword arguments for runUntilFieldsDecayed
21 * EL-01/12/2009 : alignment with version 0.8 - III
22 * EL-01/12/2009 : release 1.0 / added info about environment variables for inline C/C++
23
24
25
26**1. The general structure of a python-meep program**
27-----------------------------------------------------
28
29In general terms, a python-meep program can be structured as follows :
30
31 * import the python-meep binding :
32 ``from meep import *``
33 This will load the library ``_meep.so`` and Python-files ``meep.py`` and ``python_meep.py`` from path ``/usr/local/lib/python2.6/dist-packages/``
34
35 If you are running in MPI mode (multiprocessor, see section 9), then you have to import module ``meep_mpi`` instead :
36 ``from meep_mpi import *``
37
38 * define a computational grid volume
39 See section 2 below which explains usage of the ``grid_volume`` class.
40
41 * define the waveguide structure (describing the geometry, PML and materials)
42 See section 3 below which explains usage of the ``structure`` class.
43
44 * create an object which will hold the calculated fields
45 See section 4 below which explains usage of the ``field`` class.
46
47 * define the sources
48 See section 5 below which explains usage of the ``add_point_source`` and ``add_volume_source`` functions.
49
50 * run the simulation (iterate over the time-steps)
51 See section 6 below.
52
53Section 7 gives details about defining and retrieving fluxes.
54
55Section 9 gives some complete examples.
56
57Section 10 outlines some differences between Scheme-Meep and Python-Meep.
58
59
60**2. Defining the computational grid volume**
61---------------------------------------------
62
63The following set of 'factory functions' is provided, aimed at creating a ``grid_volume`` object. The first arguments define the size of the computational volume, the last argument is the computational grid resolution (in pixels per distance unit).
64 * ``volcyl(rsize, zsize, resolution)``
65 Defines a cyclical computational grid volume.
66 * ``volone(zsize, resolution)`` *alternatively called* ``vol1d(zsize, resolution)``
67 Defines a 1-dimensional computational grid volume along the Z-axis.
68 * ``voltwo(xsize, ysize, resolution)`` *alternatively called* ``vol2d(xsize, ysize, a)``
69 Defines a 2-dimensional computational grid volumes along the X- and Y-axes
70 * ``vol3d(xsize, ysize, zsize, resolution)``
71 Defines a 3-dimensional computational grid volume.
72
73 e.g.: ``v = volone(6, 10)`` defines a 1-dimensional computational volume of lenght 6, with 10 pixels per distance unit.
74
75
76**3. Defining the waveguide structure**
77---------------------------------------
78
79The waveguide structure is defined using the class ``structure``, of which the constructor has the following arguments :
80
81 * *required* : the computational grid volume (a reference to an object of type ``grid_volume``, see section 2 above)
82
83 * *required* : a function defining the dielectric properties of the materials in the computational grid volume (thus describing the actual waveguide structure). For all-air, the predefined function 'one' can be used (epsilon = constant value 1). See note 3.1 below for more information about defining your own custom material function.
84
85 * *optional* : a boundary region: this is a reference to an object of type ``boundary_region``. There are a number of predefined functions that can be used to create such an object :
86 - ``no_pml()`` describing a conditionless boundary region (no PML)
87 - ``pml(thickness)`` : decribing a perfectly matching layer (PML) of a certain thickness (double value) on the boundaries in all directions.
88 - ``pml(thickness, direction)`` : decribing a perfectly matching layer (PML) of a certain thickness (double value) in a certain direction (``X, Y, Z, R or P``).
89 - ``pml(thickness, direction, boundary_side)`` : describing a PML of a certain thickness (double value), in a certain direction (``X, Y, Z, R or P``) and on the ``High`` or ``Low`` side. E.g. if boundary_side is ``Low`` and direction is ``X``, then a PML layer is added to the −x boundary. The default puts PML layers on both sides of the direction.
90
91 * *optional* : a function defining a symmetry to exploit, in order to speed up the FDTD calculation (reference to an object of type ``symmetry``). The following predefined functions can be used to create a ``symmetry`` object:
92 - ``identity`` : no symmetry
93 - ``rotate4(direction, grid_volume)`` : defines a 90° rotational symmetry with 'direction' the axis of rotation.
94 - ``rotate2(direction, grid_volume)`` : defines a 180° rotational symmetry with 'direction' the axis of rotation.
95 - ``mirror(direction, grid_volume)`` : defines a mirror symmetry plane with 'direction' normal to the mirror plane.
96 - ``r_to_minus_r_symmetry`` : defines a mirror symmetry in polar coordinates
97
98 * optional: the number of chunks in which to split up the calculated geometry. If you leave this empty, it is auto-configured. Otherwise, you would set this to a factor which is a multiple of the number of processors in your MPI run (for multiprocessor configuration).
99
100 e.g. : if ``v`` is a variable pointing to the computational grid volume, then :
101 ``s = structure(v, one)`` defines a structure with all air (eps=1),
102 which is equivalent to:
103 ``s = structure(v, one, no_pml(), identity(), 1)``
104
105 Another example : ``s = structure(v, EPS, pml(0.1,Y) )`` with EPS a custom material function, which is explained in the note below.
106
107
1083.1. Defining a material function
109________________________________________
110
111In order to describe the geometry of the waveguide, we have to provide a 'material function' returning the dielectric variable epsilon as a function of the position (identified by a vector). In python-meep, we can do this by defining a class that inherits from class ``Callback``. Through this inheritance, the core meep library (written in C++) will be able to call back to the Python function which describes the material properties.
112It is also possible (and faster) to write your material function in inline C/C++ (see 3.3)
113
114E.g. :
115
116::
117
118 class epsilon(Callback): #inherit from Callback for integration with the meep core library
119 def __init__(self):
120 Callback.__init__(self)
121 def double_vec(self,vec): #override of function in the Callback class to set the eps function
122 self.set_double(self.eps(vec))
123 return
124 def eps(self,vec): #return the epsilon value for a certain point (indicated by the vector v)
125 v = vec
126 r = v.x()*v.x() + v.y()*v.y()
127 dr = sqrt(r)
128 while dr>1:
129 dr-=1
130 if dr > 0.7001:
131 return 12.0
132 return 1.0
133
134Please note the **brackets** when referring to the x- and y-components of the vector ``vec``. These are **crucial** : no error message will be thrown if you refer to it as vec.x or vec.y, but the value will always be zero.
135So, one should write : ``vec.x()`` and ``vec.y()``.
136
137The meep-python library has a 'global' variable EPS, which is used as a reference for communication between the Meep core library and the Python code. We assign our epsilon-function as follows to the global EPS variable :
138
139::
140
141 set_EPS_Callback(epsilon().__disown__())
142 s = structure(v, EPS, no_pml(), identity())
143
144
145The call to function ``__disown__()`` is for memory management purposes and is *absolutely required*. An improvement of the python-meep binding could consist of making this call transparant for the end user. But for now, the user must manually provide it.
146
147***Important remark*** : at the end of our program, we should call : ``del_EPS_Callback()`` in order to clean up the global variable.
148
149For better performance, you can define your EPS material function with inline C/C++ : we refer to section 3.3 for details about this.
150
1513.2 Eps-averaging
152_________________
153
154EPS-averaging (anisotrpic averaging) is disabled by default, making this behaviour consistent with the behaviour of the Meep C++ core.
155
156You can enable EPS-averaging using the function ``use_averaging`` :
157
158::
159
160 #enable EPS-averaging
161 use_averaging(True)
162 ...
163 #disable EPS-averaging
164 use_averaging(False)
165 ...
166
167
168Enabling EPS-averaging results in slower performance, but more accurate results.
169
170
1713.3. Defining a material function with inline C/C++
172_________________________________________________________
173
174The approach described in 3.1 lets the Meep core library call back to Python for every query of the epsilon-function. This creates a lot of overhead.
175An approach which has a lot better performance is to define this epsilon-function with an inline C-function or C++ class.
176
177* If our epsilon-function needs *no other parameters than the position vector (X, Y, Z)*, then we can suffice with an inline C-function (the geometry dependencies are then typically hardcoded).
178
179* If our epsilon-function needs to base it's calculation on *a more complex set of parameters (e.g. parameters depending on the geometry)*, then we have to write a C++ class.
180
181For example, in the bent-waveguide example (section 8.3), we can define a generic C++ class which can return the epsilon-value for both the "bend" and "no bend" case, with variable size parameters.
182We can also take a simpler approach (section 8.2) and write a function in which the geometry size parameters are hardcoded : we then need 2 inline C-functions : one for the "bend" case and one for the "no bend" case.
183
184Make sure the following environment variables are defined :
185 * MEEP_INCLUDE : should point to the path containing meep.hpp (and a subdirectory 'meep' with vec.hpp and mympi.hpp), e.g.: ``/usr/include``
186 * MEEP_LIB : should point to the path containing libmeep.so, e.g. : ``/usr/lib``
187 * PYTHONMEEP_INCLUDE : should point to the path containing custom.hpp, e.g. : ``/usr/local/lib/python2.6/dist-packages``
188
189
1903.3.1 Inline C-function
191.......................
192
193First we create a header file, e.g. "eps_function.hpp" which contains our EPS-function.
194Not that the geometry dependencies are hardcoded (``upperLimitHorizontalWg = 4`` and ``lowerLimitHorizontalWg = 5``).
195
196::
197
198
199 namespace meep
200 {
201 static double myEps(const vec &v) {
202 double xCo = v.x();
203 double yCo = v.y();
204 double upperLimitHorizontalWg = 4;
205 double lowerLimitHorizontalWg = 5;
206 if ((yCo < upperLimitHorizontalWg) || (yCo > lowerLimitHorizontalWg)){
207 return 1.0;
208 }
209 else return 12.0;
210 }
211 }
212
213
214Then, in the Python program, we prepare and set the callback function as shown below.
215``prepareCallbackCfunction`` returns a pointer to the C-function, which we deliver to the Meep core using ``set_EPS_CallbackInlineFunction``.
216
217::
218
219 def initEPS(isWgBent):
220 funPtr = prepareCallbackCfunction("myEps","eps_function.hpp") #name of your function / name of header file
221 set_EPS_CallbackInlineFunction(funPtr)
222 print "EPS function successfully set."
223 return funPtr
224
225We refer to section 8.2 below for a full example.
226
227
2283.3.2 Inline C++-class
229......................
230
231A more complex approach is to have a C++ object that can accept more parameters when it is constructed.
232For example this is the case if want to change the parameters of the geometry from inside Python without touching the C++ code.
233
234We create a header file "eps_class.hpp" which contains the definition of the class (the class must inherit from ``Callback``).
235In the example below, the parameters ``upperLimitHorizontalWg`` and ``widthWg`` will be communicated from Python upon construction of the object.
236If these parameters then change (depending on the geometry), the C++ object will follow automatically.
237
238
239::
240
241 using namespace meep;
242
243 namespace meep
244 {
245
246 class myEpsCallBack : virtual public Callback {
247
248 public:
249 myEpsCallBack() : Callback() { };
250 ~myEpsCallBack() { cout << "Callback object destructed." << endl; };
251
252 myEpsCallBack(double upperLimitHorizontalWg, double widthWg) : Callback() {
253 _upperLimitHorizontalWg = upperLimitHorizontalWg;
254 _widthWg = widthWg;
255 };
256
257 double double_vec(const vec &v) { //return the EPS-value, depending on the position vector
258 double eps = myEps(v, _upperLimitHorizontalWg, _widthWg);
259 return eps;
260 };
261
262 complex<double> complex_vec(const vec &x) { return 0; }; //no need to implement
263 complex<double> complex_time(const double &t) { return 0; }; //no need to implement
264
265
266 private:
267 double _upperLimitHorizontalWg;
268 double _widthWg;
269
270 double myEps(const vec &v, double upperLimitHorizontalWg, double widthWg) {
271 double xCo = v.x();
272 double yCo = v.y();
273 if ((yCo < upperLimitHorizontalWg) || (yCo > upperLimitHorizontalWg+widthWg)){
274 return 1.0;
275 }
276 }
277 return 12.0;
278 }
279
280 };
281
282 }
283
284
285The syntax in Python is a little bit more complex in this case.
286
287We will need to import the module ``scipy.weave`` :
288
289``from scipy.weave import *``
290
291(this is not required for the previous case of a simple inline function)
292
293First we create a list with the names of the parameters that we want to pass to the C++ class. These variables must be declared in the scope where the ``inline`` function call happens (see below).
294
295``c_params = ['upperLimitHorizontalWg','widthWg']``
296
297Then, we prepare the code snippet, using the function ``prepareCallbackCObjectCode`` and passing the class name and parameter names list.
298
299``c_code = prepareCallbackCObjectCode("myEpsCallBack", c_params)``
300
301Finally, we call the ``inline`` function, passing :
302 * the code snippet
303 * the list of parameter names
304 * the inline libraries, include directories and headers (helper functions are provided for this, see below). The call to ``getInlineHeaders`` should receive the name of the header file (with the definition of the C++ class) as an argument.
305
306``funPtr = inline(c_code,c_params, libraries=getInlineLibraries(), include_dirs = getInlineInclude(), headers = getInlineHeaders("eps_class.hpp") )``
307
308::
309
310
311 def initEPS():
312 #the set of parameters that we want to pass to the Callback object upon construction
313 #all these variables must be declared in the scope where the "inline" function call happens
314 c_params = ['upperLimitHorizontalWg','widthWg']
315 #the C-code snippet for constructing the Callback object
316 c_code = prepareCallbackCObjectCode("myEpsCallBack", c_params)
317 #do the actual inline C-call and fetch the pointer to the Callback object
318 funPtr = inline(c_code,c_params, libraries=getInlineLibraries(), include_dirs = getInlineInclude(), headers = getInlineHeaders("eps_class.hpp") )
319 #set the pointer to the callback object in the Python-meep core
320 set_EPS_CallbackInlineObject(funPtr)
321 print "EPS function successfully set."
322 return
323
324
325We refer to section 8.3 below for a full example.
326
327
328
329**4. Defining the initial field**
330---------------------------------
331
332This is optional.
333
334We create an object of type ``fields``, which will contain the calculated field.
335
336We must first create a Python class that inherits from class ``Callback`` and that will define the function for initialization of the field. Inheritance from class ``Callback`` is required, because the core meep library (written in C++) will have to call back to the Python function. For example, let's call our initialization class ``fi``.
337
338::
339
340 class fi(Callback): #inherit from Callback for integration with the meep core library
341 def __init__(self):
342 Callback.__init__(self)
343 def complex_vec(self,v): #override of function in the Callback class to set the field initialization function
344 #return the field value for a certain point (indicated by the vector v)
345 return complex(1.0,0)
346
347The meep-python library has a 'global' variable INIF, that is used to bind the meep core library to our Python field initialization class. To set INIF, we have to use the following statement :
348
349 ``set_INIF_Callback(fi().__disown__()) #link the INIF variable to the fi class``
350
351We refer to section 3-note1 for more information about the function ``__disown__()``.
352
353E.g.: If ``s`` is a variable pointing to the structure and ``comp`` denotes the component which we are initializing, then the complete field initialization code looks as follows :
354
355::
356
357 f = fields(s)
358 comp = Hy
359 f.initialize_field(comp, INIF)
360
361
362***Important remark*** : at the end of our program, we should then call : ``del_INIF_Callback()`` in order to clean up the global variable.
363
364The call to ``initialize_field`` is not mandatory. If the initial conditions are zeros for all components, then we can rely on the automatic initialization at creation of the object.
365
366We can additionally define **Bloch-periodic boundary conditions** over the field. This is done with the ``use_bloch`` function of the field class, e.g. :
367
368 ``f.use_bloch(vec(0.0))``
369
370*to be further elaborated - what is the exact meaning of the vector argument? (not well understood at this time)*
371
372
373
374**5. Defining the sources**
375---------------------------
376
377The definition of the current sources can be done through 2 functions of the ``fields`` class :
378 * ``add_point_source(component, src_time, vec, complex)``
379 * ``add_volume_source(component, src_time, volume, complex)``
380
381
382Each require as arguments an electromagnetic component (e.g. ``Ex, Ey, ...`` and ``Hx, Hy, ...``) and an object of type ``src_time``, which specifies the time dependence of the source (see below).
383
384For a point source, we must specify the center point of the current source using a vector (object of type ``vec``).
385
386For a volume source, we must specify an object of type ``volume`` (*to be elablorated*).
387
388The last argument is an overall complex amplitude number, multiplying the current source (default 1.0).
389
390The following variants are available :
391 * ``add_point_source(component, double, double, double, double, vec centerpoint, complex amplitude, int is_continuous)``
392 * This is a shortcut function so that no ``src_time`` object must be created. *This function is preferably used for point sources.*
393 * The four real arguments define the central frequency, spectral width, peaktime and cutoff.
394
395 * ``add_volume_source(component, src_time, volume)``
396
397 * ``add_volume_source(component, src_time, volume, AMPL)``
398 * AMPL is a built-in reference to a callback function. Such a callback function returns a factor to multiply the source amplitude with (complex value). It receives 1 parameter, i.e. a vector indicating a position RELATIVE to the CENTER of the source. See the example below.
399
400
401Three classes, inheriting from ``src_time``, are predefined and can be used off the shelf :
402 * ``gaussian_src_time`` for a Gaussian-pulse source. The constructor demands 2 arguments of type double :
403 * the center frequency ω, in units of 2πc
404 * the frequency width w used in the Gaussian
405 * ``continuous_src_time`` for a continuous-wave source proportional to exp(−iωt). The constructor demands 4 arguments :
406 * the frequency ω, in units 2πc/distance (complex number)
407 * the temporal width of smoothing (default 0)
408 * the start time (default 0)
409 * the end time (default infinity = never turn off)
410 * ``custom_src_time`` for a user-specified source function f(t) with start/end times. The constructor demands 4 arguments :
411 * The function f(t) specifying the time-dependence of the source
412 * *...(2nd argument unclear, to be further elaborated)...*
413 * the start time of the source (default -infinity)
414 * the end time of the source (default +infinity)
415
416For example, in order to define a continuous line source of length 1, from point (6,3) to point (6,4) in 2-dimensional geometry :
417
418::
419
420 #define a continuous source
421 srcFreq = 0.125
422 srcWidth = 20
423 src = continuous_src_time(srcFreq, srcWidth, 0, infinity)
424 srcComp = Ez
425 #make it a line source of size 1 starting on position(6,3)
426 srcGeo = volume(vec(6,3),vec(6,4))
427 f.add_volume_source(srcComp, src, srcGeo)
428
429
430Here is an example of the implementation of a callback function for the amplitude factor :
431
432::
433
434 class amplitudeFactor(Callback):
435 def __init__(self):
436 Callback.__init__(self)
437 master_printf("Callback function for amplitude factor activated.\n")
438
439 def complex_vec(self,vec):
440 #BEWARE, these are coordinates RELATIVE to the source center !!!!
441 x = vec.x()
442 y = vec.y()
443 master_printf("Fetching amplitude factor for x=%f - y=%f\n" %(x,y) )
444 result = complex(1.0,0)
445 return result
446
447 ...
448 #define a continuous source
449 srcFreq = 0.125
450 srcWidth = 20
451 src = continuous_src_time(srcFreq, srcWidth, 0, infinity)
452 srcComp = Ez
453 #make it a line source of size 1 starting on position(6,3)
454 srcGeo = volume(vec(6,3),vec(6,4))
455 #create callback object for amplitude factor
456 af = amplitudeFactor()
457 set_AMPL_Callback(af.__disown__())
458 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, AMPL)
459
460
461**6. Running the simulation, retrieving field values and exporting HDF5 files**
462-------------------------------------------------------------------------------
463
464We can now time-step and retrieve various field values along the way.
465The actual time step value can be retrieved or set through the variable ``f.dt``.
466
467The default time step in Meep is : ``Courant factor / resolution`` (in FDTD, the Courant factor relates the time step size to the spatial discretization: cΔt = SΔx. Default for S is 0.5). If no further parametrization is done, then this default value is used.
468
469To trigger a step in time, you call the function ``f.step()``.
470
471To step until the source has fully decayed :
472
473::
474
475 while (f.time() < f.last_source_time()):
476 f.step()
477
478The function ``runUntilFieldsDecayed`` mimicks the behaviour of 'stop-when-fields-decayed' in Meep-Scheme.
479This will run time steps until the source has decayed to 0.001 of the peak amplitude. After that, by default an additional 50 time steps will be run.
480The function has 7 arguments, of which 4 are mandatory and 3 are optional keywords arguments :
481* 4 regular arguments : reference to the field, reference to the computational grid volume, the source component, the monitor point.
482* keyword argument ``pHDF5OutputFile`` : reference to a HDF5 file (constructed with the function ``prepareHDF5File``); default : None (no ouput to files)
483* keyword argument ``pH5OutputIntervalSteps`` : step interval for output to HDF5 (default : 50)
484* keyword argument ``pDecayedStopAfterSteps`` : the number of steps to continue after the source has decayed to 0.001 of the peak amplitude at the probing point (default: 50)
485
486We further refer to section 8 below where this function is applied in an example.
487
488A rich functionality is available for retrieving field information. Some examples :
489
490 * ``f.energy_in_box(v.surroundings())``
491 * ``f.electric_energy_in_box(v.surroundings())``
492 * ``f.magnetic_energy_in_box(v.surroundings())``
493 * ``f.thermo_energy_in_box(v.surroundings())``
494 * ``f.total_energy()``
495 * ``f.field_energy_in_box(v.surroundings())``
496 * ``f.field_energy_in_box(component, v.surroundings())`` where the first argument is the electromagnetic component (``Ex, Ey, Ez, Er, Ep, Hx, Hy, Hz, Hr, Hp, Dx, Dy, Dz, Dp, Dr, Bx, By, Bz, Bp, Br, Dielectric`` or ``Permeability``)
497 * ``f.flux_in_box(X, v.surroundings())`` where the first argument is the direction (``X, Y, Z, R`` or ``P``)
498
499We can probe the field at certain points by defining a *monitor point* as follows :
500
501::
502
503 m = monitor_point()
504 p = vec(2.10) #vector identifying the point that we want to probe
505 f.get_point(m, p)
506 m.get_component(Hx)
507
508We can export the dielectric function and e.g. the Ex component of the field to HDF5 files as follows :
509
510::
511
512 #make sure you start your Python session with 'sudo' or write rights to the current path
513 feps = prepareHDF5File("eps.h5")
514 f.output_hdf5(Dielectric, v.surroundings(), feps) #export the Dielectric structure so that we can visually verify it
515 fex = prepareHDF5File("ex.h5")
516 while (f.time() < f.last_source_time()):
517 f.step()
518 f.output_hdf5(Ex, v.surroundings(), fex, 1) #export the Ex component, appending to the file "ex.h5"
519
520
521
522**7. Defining and retrieving fluxes**
523--------------------------------------
524
525First we define a flux plane.
526This is done through the creation of an object of type ``volume`` (specifying 2 vectors as arguments).
527
528Then we apply this flux plane to the field, specifying 4 parameters :
529 * the reference to the ``volume`` object
530 * the minimum frequency (in the example below, this is ``srcFreqCenter-(srcPulseWidth/2.0)``)
531 * the maximum frequency (in the example below this is ``srcFreqCenter+(srcPulseWidth/2.0)`` )
532 * the number of discrete frequencies that we want to monitor in the flux (in the example below, this is 100).
533
534After running the simulation, we can retrieve the flux values through the function ``getFluxData()`` : this returns a 2-dimensional array with the frequencies and actual flux values.
535
536E.g., if ``f`` is the field, then we proceed as follows :
537
538::
539
540 #define the flux plane and flux parameters
541 fluxplane = volume(vec(1,2),vec(1,3))
542 flux = f.add_dft_flux_plane(fluxplane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
543
544 #run the calculation
545 while (f.time() < f.last_source_time()):
546 f.step()
547
548 #retrieve the flux data
549 fluxdata = getFluxData(flux)
550 frequencies = fluxdata[0]
551 fluxvalues = fluxdata[1]
552
553
554
555**8. The "90 degree bent waveguide example in Python**
556------------------------------------------------------
557
558We have ported the "90 degree bent waveguide" example from the Meep-Scheme tutorial to Python.
559
560The original example can be found on the following URL : http://ab-initio.mit.edu/wiki/index.php/Meep_Tutorial
561(section 'A 90° bend').
562
563You can find the source code below and also in the ``/samples/bent_waveguide`` directory of the Python-Meep distribution.
564
565Sections 8.2 and 8.3 contain the same example but with the EPS-callback function as inline C-function and inline C++-class.
566
567The following animated gifs can be produced from the HDF5-files (see the script included in directory 'samples') :
568
569.. image:: images/bentwgNB.gif
570
571.. image:: images/bentwgB.gif
572
573
574And here is the graph of the transmission, reflection and loss fluxes, showing the same results as the example in Scheme:
575
576.. image:: images/fluxes.png
577 :height: 315
578 :width: 443
579
580
5818.1 With a Python class as EPS-function
582________________________________________
583
584
585A bottleneck in this version is the epsilon-function, which is written in Python.
586This means that the Meep core library must do a callback to the Python function, which creates a lot of overhead.
587An approach which has a much better performance is to write this EPS-function in C : the Meep core library can then directly call back to a C-function.
588These approaches are described in 8.2 and 8.3.
589
590::
591
592 from meep import *
593 from math import *
594 from python_meep import *
595 import numpy
596 import matplotlib.pyplot
597 import sys
598
599 res = 10.0
600 gridSizeX = 16.0
601 gridSizeY = 32.0
602 padSize = 4.0
603 wgLengthX = gridSizeX - padSize
604 wgLengthY = gridSizeY - padSize
605 wgWidth = 1.0 #width of the waveguide
606 wgHorYCen = padSize + wgWidth/2.0 #horizontal waveguide center Y-pos
607 wgVerXCen = wgLengthX - wgWidth/2.0 #vertical waveguide center X-pos (in case there is a bend)
608 srcFreqCenter = 0.15 #gaussian source center frequency
609 srcPulseWidth = 0.1 #gaussian source pulse width
610 srcComp = Ez #gaussian source component
611
612 #this function plots the waveguide material as a function of a vector(X,Y)
613 class epsilon(Callback):
614 def __init__(self, pIsWgBent):
615 Callback.__init__(self)
616 self.isWgBent = pIsWgBent
617 def double_vec(self,vec):
618 if (self.isWgBent): #there is a bend
619 if ((vec.x()<wgLengthX) and (vec.y() >= padSize) and (vec.y() <= padSize+wgWidth)):
620 return 12.0
621 elif ((vec.x()>=wgLengthX-wgWidth) and (vec.x()<=wgLengthX) and vec.y()>= padSize ):
622 return 12.0
623 else:
624 return 1.0
625 else: #there is no bend
626 if ((vec.y() >= padSize) and (vec.y() <= padSize+wgWidth)):
627 return 12.0
628 else:
629 return 1.0
630
631 def createField(pCompVol, pWgLengthX, pWgWidth, pIsWgBent, pSrcFreqCenter, pSrcPulseWidth, pSrcComp):
632 #we create a structure with PML of thickness = 1.0 on all boundaries,
633 #in all directions,
634 #using the material function EPS
635 material = epsilon(pIsWgBent)
636 set_EPS_Callback(material.__disown__())
637 s = structure(pCompVol, EPS, pml(1.0) )
638 f = fields(s)
639 #define a gaussian line source of length 'wgWidth' at X=wgLength/2, Y=padSize
640 srcGaussian = gaussian_src_time(pSrcFreqCenter, pSrcPulseWidth )
641 srcGeo = volume(vec(1.0,padSize),vec(1.0,padSize+pWgWidth))
642 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, 1)
643 print "Field created..."
644 return f
645
646
647 #FIRST WE WORK OUT THE CASE WITH NO BEND
648 #----------------------------------------------------------------
649 print "*1* Starting the case with no bend..."
650 #create the computational grid
651 noBendVol = voltwo(gridSizeX,gridSizeY,res)
652
653 #create the field
654 wgBent = 0 #no bend
655 noBendField = createField(noBendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
656
657 bendFnEps = "./bentwgNB_Eps.h5"
658 bendFnEz = "./bentwgNB_Ez.h5"
659 #export the dielectric structure (so that we can visually verify the waveguide structure)
660 noBendDielectricFile = prepareHDF5File(bendFnEps)
661 noBendField.output_hdf5(Dielectric, noBendVol.surroundings(), noBendDielectricFile)
662
663 #create the file for the field components
664 noBendFileOutputEz = prepareHDF5File(bendFnEz)
665
666 #define the flux plane for the reflected flux
667 noBendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
668 noBendReflectedFluxPlane = volume(vec(noBendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
669 noBendReflectedFlux = noBendField.add_dft_flux_plane(noBendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
670
671 #define the flux plane for the transmitted flux
672 noBendTransmfluxPlaneXPos = gridSizeX - 1.5; #the X-coordinate of our transmission flux plane
673 noBendTransmFluxPlane = volume(vec(noBendTransmfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendTransmfluxPlaneXPos,wgHorYCen+wgWidth))
674 noBendTransmFlux = noBendField.add_dft_flux_plane(noBendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
675
676 print "Calculating..."
677 noBendProbingpoint = vec(noBendTransmfluxPlaneXPos,wgHorYCen) #the point at the end of the waveguide that we want to probe to check if source has decayed
678 runUntilFieldsDecayed(noBendField, noBendVol, srcComp, noBendProbingpoint, noBendFileOutputEz)
679 print "Done..!"
680
681 #construct 2-dimensional array with the flux plane data
682 #see python_meep.py
683 noBendReflFlux = getFluxData(noBendReflectedFlux)
684 noBendTransmFlux = getFluxData(noBendTransmFlux)
685
686 #save the reflection flux from the "no bend" case as minus flux in the temporary file 'minusflux.h5'
687 noBendReflectedFlux.scale_dfts(-1);
688 f = open("minusflux.h5", 'w') #truncate file if already exists
689 f.close()
690 noBendReflectedFlux.save_hdf5(noBendField, "minusflux")
691
692 del_EPS_Callback()
693
694
695 #AND SECONDLY FOR THE CASE WITH BEND
696 #----------------------------------------------------------------
697 print "*2* Starting the case with bend..."
698 #create the computational grid
699 bendVol = voltwo(gridSizeX,gridSizeY,res)
700
701 #create the field
702 wgBent = 1 #there is a bend
703 bendField = createField(bendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
704
705 #export the dielectric structure (so that we can visually verify the waveguide structure)
706 bendFnEps = "./bentwgB_Eps.h5"
707 bendFnEz = "./bentwgB_Ez.h5"
708 bendDielectricFile = prepareHDF5File(bendFnEps)
709 bendField.output_hdf5(Dielectric, bendVol.surroundings(), bendDielectricFile)
710
711 #create the file for the field components
712 bendFileOutputEz = prepareHDF5File(bendFnEz)
713
714 #define the flux plane for the reflected flux
715 bendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
716 bendReflectedFluxPlane = volume(vec(bendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(bendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
717 bendReflectedFlux = bendField.add_dft_flux_plane(bendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
718
719 #load the minused reflection flux from the "no bend" case as initalization
720 bendReflectedFlux.load_hdf5(bendField, "minusflux")
721
722
723 #define the flux plane for the transmitted flux
724 bendTransmfluxPlaneYPos = padSize + wgLengthY - 1.5; #the Y-coordinate of our transmission flux plane
725 bendTransmFluxPlane = volume(vec(wgVerXCen - wgWidth,bendTransmfluxPlaneYPos),vec(wgVerXCen + wgWidth,bendTransmfluxPlaneYPos))
726 bendTransmFlux = bendField.add_dft_flux_plane(bendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
727
728 print "Calculating..."
729 bendProbingpoint = vec(wgVerXCen,bendTransmfluxPlaneYPos) #the point at the end of the waveguide that we want to probe to check if source has decayed
730 runUntilFieldsDecayed(bendField, bendVol, srcComp, bendProbingpoint, bendFileOutputEz)
731 print "Done..!"
732
733 #construct 2-dimensional array with the flux plane data
734 #see python_meep.py
735 bendReflFlux = getFluxData(bendReflectedFlux)
736 bendTransmFlux = getFluxData(bendTransmFlux)
737
738 del_EPS_Callback()
739
740 #SHOW THE RESULTS IN A PLOT
741 frequencies = bendReflFlux[0] #should be equal to bendTransmFlux.keys() or noBendTransmFlux.keys() or ...
742 Ptrans = [x / y for x,y in zip(bendTransmFlux[1], noBendTransmFlux[1])]
743 Prefl = [ abs(x / y) for x,y in zip(bendReflFlux[1], noBendTransmFlux[1]) ]
744 Ploss = [ 1-x-y for x,y in zip(Ptrans, Prefl)]
745
746 matplotlib.pyplot.plot(frequencies, Ptrans, 'bo')
747 matplotlib.pyplot.plot(frequencies, Prefl, 'ro')
748 matplotlib.pyplot.plot(frequencies, Ploss, 'go' )
749
750 matplotlib.pyplot.show()
751
752
7538.2 With an inline C-function as EPS-function
754______________________________________________
755
756The header file "eps_function.hpp" :
757
758::
759
760 using namespace meep;
761
762 namespace meep
763 {
764 static double myEps(const vec &v, bool isWgBent) {
765 double xCo = v.x();
766 double yCo = v.y();
767 double upperLimitHorizontalWg = 4;
768 double wgLengthX = 12;
769 double leftLimitVerticalWg = 11;
770 double lowerLimitHorizontalWg = 5;
771 if (isWgBent){ //there is a bend
772 if ((yCo < upperLimitHorizontalWg) || (xCo>wgLengthX)){
773 return 1.0;
774 }
775 else {
776 if ((xCo < leftLimitVerticalWg) && (yCo > lowerLimitHorizontalWg)) {
777 return 1.0;
778 }
779 else {
780 return 12.0;
781 }
782 }
783 }
784 else { //there is no bend
785 if ((yCo < upperLimitHorizontalWg) || (yCo > lowerLimitHorizontalWg)){
786 return 1.0;
787 }
788 }
789 return 12.0;
790 }
791
792 static double myEpsBentWg(const vec &v) {
793 return myEps(v, true);
794 }
795
796 static double myEpsStraightWg(const vec &v) {
797 return myEps(v, false);
798 }
799 }
800
801
802
803And the actual Python program :
804
805
806::
807
808
809 from meep import *
810
811 from math import *
812 import numpy
813 import matplotlib.pyplot
814 import sys
815
816 res = 10.0
817 gridSizeX = 16.0
818 gridSizeY = 32.0
819 padSize = 4.0
820 wgLengthX = gridSizeX - padSize
821 wgLengthY = gridSizeY - padSize
822 wgWidth = 1.0 #width of the waveguide
823 upperLimitHorizontalWg = padSize
824 lowerLimitHorizontalWg = padSize+wgWidth
825 leftLimitVerticalWg = wgLengthX-wgWidth
826 wgHorYCen = padSize + wgWidth/2.0 #horizontal waveguide center Y-pos
827 wgVerXCen = wgLengthX - wgWidth/2.0 #vertical waveguide center X-pos (in case there is a bend)
828 srcFreqCenter = 0.15 #gaussian source center frequency
829 srcPulseWidth = 0.1 #gaussian source pulse width
830 srcComp = Ez #gaussian source component
831
832 def initEPS(isWgBent):
833 if (isWgBent):
834 funPtr = prepareCallbackCfunction("myEpsBentWg","eps_function.hpp")
835 else:
836 funPtr = prepareCallbackCfunction("myEpsStraightWg","eps_function.hpp")
837 set_EPS_CallbackInlineFunction(funPtr)
838 print "EPS function successfully set."
839 return funPtr
840
841 def createField(pCompVol, pWgLengthX, pWgWidth, pIsWgBent, pSrcFreqCenter, pSrcPulseWidth, pSrcComp):
842 #we create a structure with PML of thickness = 1.0 on all boundaries,
843 #in all directions,
844 #using the material function EPS
845 s = structure(pCompVol, EPS, pml(1.0) )
846 f = fields(s)
847 #define a gaussian line source of length 'wgWidth' at X=wgLength/2, Y=padSize
848 srcGaussian = gaussian_src_time(pSrcFreqCenter, pSrcPulseWidth )
849 srcGeo = volume(vec(1.0,padSize),vec(1.0,padSize+pWgWidth))
850 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, 1)
851 print "Field created..."
852 return f
853
854
855 master_printf("BENT WAVEGUIDE SAMPLE WITH INLINE C-FUNCTION FOR EPS\n")
856
857 master_printf("Running on %d processor(s)...\n",count_processors())
858
859 #FIRST WE WORK OUT THE CASE WITH NO BEND
860 #----------------------------------------------------------------
861 master_printf("*1* Starting the case with no bend...")
862
863 #set EPS material function
864 initEPS(0)
865
866 #create the computational grid
867 noBendVol = voltwo(gridSizeX,gridSizeY,res)
868
869 #create the field
870 wgBent = 0 #no bend
871 noBendField = createField(noBendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
872
873 bendFnEps = "./bentwgNB_Eps.h5"
874 bendFnEz = "./bentwgNB_Ez.h5"
875 #export the dielectric structure (so that we can visually verify the waveguide structure)
876 noBendDielectricFile = prepareHDF5File(bendFnEps)
877 noBendField.output_hdf5(Dielectric, noBendVol.surroundings(), noBendDielectricFile)
878
879 #create the file for the field components
880 noBendFileOutputEz = prepareHDF5File(bendFnEz)
881
882 #define the flux plane for the reflected flux
883 noBendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
884 noBendReflectedFluxPlane = volume(vec(noBendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
885 noBendReflectedFlux = noBendField.add_dft_flux_plane(noBendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
886
887 #define the flux plane for the transmitted flux
888 noBendTransmfluxPlaneXPos = gridSizeX - 1.5; #the X-coordinate of our transmission flux plane
889 noBendTransmFluxPlane = volume(vec(noBendTransmfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendTransmfluxPlaneXPos,wgHorYCen+wgWidth))
890 noBendTransmFlux = noBendField.add_dft_flux_plane(noBendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
891
892 master_printf("Calculating...")
893 noBendProbingpoint = vec(noBendTransmfluxPlaneXPos,wgHorYCen) #the point at the end of the waveguide that we want to probe to check if source has decayed
894 runUntilFieldsDecayed(noBendField, noBendVol, srcComp, noBendProbingpoint, noBendFileOutputEz)
895 master_printf("Done..!")
896
897 #construct 2-dimensional array with the flux plane data
898 #see python_meep.py
899 noBendReflFlux = getFluxData(noBendReflectedFlux)
900 noBendTransmFlux = getFluxData(noBendTransmFlux)
901
902 #save the reflection flux from the "no bend" case as minus flux in the temporary file 'minusflux.h5'
903 noBendReflectedFlux.scale_dfts(-1);
904 f = open("minusflux.h5", 'w') #truncate file if already exists
905 f.close()
906 noBendReflectedFlux.save_hdf5(noBendField, "minusflux")
907
908 del_EPS_Callback() #destruct the inline-created object
909
910
911 #AND SECONDLY FOR THE CASE WITH BEND
912 #----------------------------------------------------------------
913 master_printf("*2* Starting the case with bend...")
914
915 #set EPS material function
916 initEPS(1)
917
918 #create the computational grid
919 bendVol = voltwo(gridSizeX,gridSizeY,res)
920
921 #create the field
922 wgBent = 1 #there is a bend
923 bendField = createField(bendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
924
925 #export the dielectric structure (so that we can visually verify the waveguide structure)
926 bendFnEps = "./bentwgB_Eps.h5"
927 bendFnEz = "./bentwgB_Ez.h5"
928 bendDielectricFile = prepareHDF5File(bendFnEps)
929 bendField.output_hdf5(Dielectric, bendVol.surroundings(), bendDielectricFile)
930
931 #create the file for the field components
932 bendFileOutputEz = prepareHDF5File(bendFnEz)
933
934 #define the flux plane for the reflected flux
935 bendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
936 bendReflectedFluxPlane = volume(vec(bendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(bendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
937 bendReflectedFlux = bendField.add_dft_flux_plane(bendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
938
939 #load the minused reflection flux from the "no bend" case as initalization
940 bendReflectedFlux.load_hdf5(bendField, "minusflux")
941
942
943 #define the flux plane for the transmitted flux
944 bendTransmfluxPlaneYPos = padSize + wgLengthY - 1.5; #the Y-coordinate of our transmission flux plane
945 bendTransmFluxPlane = volume(vec(wgVerXCen - wgWidth,bendTransmfluxPlaneYPos),vec(wgVerXCen + wgWidth,bendTransmfluxPlaneYPos))
946 bendTransmFlux = bendField.add_dft_flux_plane(bendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
947
948 master_printf("Calculating...")
949 bendProbingpoint = vec(wgVerXCen,bendTransmfluxPlaneYPos) #the point at the end of the waveguide that we want to probe to check if source has decayed
950 runUntilFieldsDecayed(bendField, bendVol, srcComp, bendProbingpoint, bendFileOutputEz)
951 master_printf("Done..!")
952
953 #construct 2-dimensional array with the flux plane data
954 #see python_meep.py
955 bendReflFlux = getFluxData(bendReflectedFlux)
956 bendTransmFlux = getFluxData(bendTransmFlux)
957
958 del_EPS_Callback()
959
960 #SHOW THE RESULTS IN A PLOT
961 frequencies = bendReflFlux[0] #should be equal to bendTransmFlux.keys() or noBendTransmFlux.keys() or ...
962 Ptrans = [x / y for x,y in zip(bendTransmFlux[1], noBendTransmFlux[1])]
963 Prefl = [ abs(x / y) for x,y in zip(bendReflFlux[1], noBendTransmFlux[1]) ]
964 Ploss = [ 1-x-y for x,y in zip(Ptrans, Prefl)]
965
966 matplotlib.pyplot.plot(frequencies, Ptrans, 'bo')
967 matplotlib.pyplot.plot(frequencies, Prefl, 'ro')
968 matplotlib.pyplot.plot(frequencies, Ploss, 'go' )
969
970 matplotlib.pyplot.show()
971
972
973
9748.3 With an inline C++ class as EPS-function
975______________________________________________
976
977
978The header file "eps_class.hpp" :
979
980
981::
982
983
984 using namespace meep;
985
986 namespace meep
987 {
988
989 class myEpsCallBack : virtual public Callback {
990
991 public:
992 myEpsCallBack() : Callback() { };
993 ~myEpsCallBack() { cout << "Callback object destructed." << endl; };
994
995 myEpsCallBack(bool isWgBent,double upperLimitHorizontalWg, double leftLimitVerticalWg, double lowerLimitHorizontalWg, double wgLengthX) : Callback() {
996 _IsWgBent = isWgBent;
997 _upperLimitHorizontalWg = upperLimitHorizontalWg;
998 _leftLimitVerticalWg = leftLimitVerticalWg;
999 _lowerLimitHorizontalWg = lowerLimitHorizontalWg;
1000 _wgLengthX = wgLengthX;
1001 };
1002
1003 double double_vec(const vec &v) {
1004 double eps = myEps(v, _IsWgBent, _upperLimitHorizontalWg, _leftLimitVerticalWg, _lowerLimitHorizontalWg, _wgLengthX);
1005 //cout << "X="<<v.x()<<"--Y="<<v.y()<<"--eps="<<eps<<"-"<<_upperLimitHorizontalWg<<"--"<<_leftLimitVerticalWg<<"--"<<_lowerLimitHorizontalWg<<"--"<<_wgLengthX;
1006 return eps;
1007 };
1008
1009 complex<double> complex_vec(const vec &x) { return 0; };
1010 complex<double> complex_time(const double &t) { return 0; };
1011
1012
1013 private:
1014 bool _IsWgBent;;
1015 double _upperLimitHorizontalWg;
1016 double _leftLimitVerticalWg;
1017 double _lowerLimitHorizontalWg;
1018 double _wgLengthX;
1019
1020 double myEps(const vec &v, bool isWgBent, double upperLimitHorizontalWg, double leftLimitVerticalWg, double lowerLimitHorizontalWg, double wgLengthX) {
1021 double xCo = v.x();
1022 double yCo = v.y();
1023 if (isWgBent){ //there is a bend
1024 if ((yCo < upperLimitHorizontalWg) || (xCo>wgLengthX)){
1025 return 1.0;
1026 }
1027 else {
1028 if ((xCo < leftLimitVerticalWg) && (yCo > lowerLimitHorizontalWg)) {
1029 return 1.0;
1030 }
1031 else {
1032 return 12.0;
1033 }
1034 }
1035 }
1036 else { //there is no bend
1037 if ((yCo < upperLimitHorizontalWg) || (yCo > lowerLimitHorizontalWg)){
1038 return 1.0;
1039 }
1040 }
1041 return 12.0;
1042 }
1043
1044 };
1045
1046 }
1047
1048
1049The Python program :
1050
1051
1052::
1053
1054
1055 from meep import *
1056
1057 from math import *
1058 import numpy
1059 import matplotlib.pyplot
1060 import sys
1061
1062 from scipy.weave import *
1063
1064 res = 10.0
1065 gridSizeX = 16.0
1066 gridSizeY = 32.0
1067 padSize = 4.0
1068 wgLengthX = gridSizeX - padSize
1069 wgLengthY = gridSizeY - padSize
1070 wgWidth = 1.0 #width of the waveguide
1071 upperLimitHorizontalWg = padSize
1072 lowerLimitHorizontalWg = padSize+wgWidth
1073 leftLimitVerticalWg = wgLengthX-wgWidth
1074 wgHorYCen = padSize + wgWidth/2.0 #horizontal waveguide center Y-pos
1075 wgVerXCen = wgLengthX - wgWidth/2.0 #vertical waveguide center X-pos (in case there is a bend)
1076 srcFreqCenter = 0.15 #gaussian source center frequency
1077 srcPulseWidth = 0.1 #gaussian source pulse width
1078 srcComp = Ez #gaussian source component
1079
1080
1081 def initEPS():
1082 #the set of parameters that we want to pass to the Callback object upon construction
1083 c_params = ['isWgBent','upperLimitHorizontalWg','leftLimitVerticalWg','lowerLimitHorizontalWg','wgLengthX'] #all these variables must be globally declared in the scope where the "inline" function call happens
1084 #the C-code snippet for constructing the Callback object
1085 c_code = prepareCallbackCObjectCode("myEpsCallBack", c_params)
1086 #do the actual inline C-call and fetch the pointer to the Callback object
1087 funPtr = inline(c_code,c_params, libraries=getInlineLibraries(), include_dirs = getInlineInclude(), headers = getInlineHeaders("eps_class.hpp") )
1088 #set the pointer to the callback object in the Python-meep core
1089 set_EPS_CallbackInlineObject(funPtr)
1090 print "EPS function successfully set."
1091 return
1092
1093 def createField(pCompVol, pWgLengthX, pWgWidth, pIsWgBent, pSrcFreqCenter, pSrcPulseWidth, pSrcComp):
1094 #we create a structure with PML of thickness = 1.0 on all boundaries,
1095 #in all directions,
1096 #using the material function EPS
1097 s = structure(pCompVol, EPS, pml(1.0) )
1098 f = fields(s)
1099 #define a gaussian line source of length 'wgWidth' at X=wgLength/2, Y=padSize
1100 srcGaussian = gaussian_src_time(pSrcFreqCenter, pSrcPulseWidth )
1101 srcGeo = volume(vec(1.0,padSize),vec(1.0,padSize+pWgWidth))
1102 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, 1)
1103 print "Field created..."
1104 return f
1105
1106 master_printf("BENT WAVEGUIDE SAMPLE WITH INLINE C++ CLASS FOR EPS\n")
1107
1108 master_printf("Running on %d processor(s)...\n",count_processors())
1109
1110 #FIRST WE WORK OUT THE CASE WITH NO BEND
1111 #----------------------------------------------------------------
1112 master_printf("*1* Starting the case with no bend...")
1113
1114 #set EPS material function
1115 isWgBent = 0
1116 initEPS()
1117
1118 #create the computational grid
1119 noBendVol = voltwo(gridSizeX,gridSizeY,res)
1120
1121 #create the field
1122 wgBent = 0 #no bend
1123 noBendField = createField(noBendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
1124
1125 bendFnEps = "./bentwgNB_Eps.h5"
1126 bendFnEz = "./bentwgNB_Ez.h5"
1127 #export the dielectric structure (so that we can visually verify the waveguide structure)
1128 noBendDielectricFile = prepareHDF5File(bendFnEps)
1129 noBendField.output_hdf5(Dielectric, noBendVol.surroundings(), noBendDielectricFile)
1130
1131 #create the file for the field components
1132 noBendFileOutputEz = prepareHDF5File(bendFnEz)
1133
1134 #define the flux plane for the reflected flux
1135 noBendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
1136 noBendReflectedFluxPlane = volume(vec(noBendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
1137 noBendReflectedFlux = noBendField.add_dft_flux_plane(noBendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
1138
1139 #define the flux plane for the transmitted flux
1140 noBendTransmfluxPlaneXPos = gridSizeX - 1.5; #the X-coordinate of our transmission flux plane
1141 noBendTransmFluxPlane = volume(vec(noBendTransmfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendTransmfluxPlaneXPos,wgHorYCen+wgWidth))
1142 noBendTransmFlux = noBendField.add_dft_flux_plane(noBendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
1143
1144 master_printf("Calculating...")
1145 noBendProbingpoint = vec(noBendTransmfluxPlaneXPos,wgHorYCen) #the point at the end of the waveguide that we want to probe to check if source has decayed
1146 runUntilFieldsDecayed(noBendField, noBendVol, srcComp, noBendProbingpoint, noBendFileOutputEz)
1147 master_printf("Done..!")
1148
1149 #construct 2-dimensional array with the flux plane data
1150 #see python_meep.py
1151 noBendReflFlux = getFluxData(noBendReflectedFlux)
1152 noBendTransmFlux = getFluxData(noBendTransmFlux)
1153
1154 #save the reflection flux from the "no bend" case as minus flux in the temporary file 'minusflux.h5'
1155 noBendReflectedFlux.scale_dfts(-1);
1156 f = open("minusflux.h5", 'w') #truncate file if already exists
1157 f.close()
1158 noBendReflectedFlux.save_hdf5(noBendField, "minusflux")
1159
1160 del_EPS_Callback() #destruct the inline-created object
1161
1162
1163 #AND SECONDLY FOR THE CASE WITH BEND
1164 #----------------------------------------------------------------
1165 master_printf("*2* Starting the case with bend...")
1166
1167 #set EPS material function
1168 isWgBent = 1
1169 initEPS()
1170
1171 #create the computational grid
1172 bendVol = voltwo(gridSizeX,gridSizeY,res)
1173
1174 #create the field
1175 wgBent = 1 #there is a bend
1176 bendField = createField(bendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
1177
1178 #export the dielectric structure (so that we can visually verify the waveguide structure)
1179 bendFnEps = "./bentwgB_Eps.h5"
1180 bendFnEz = "./bentwgB_Ez.h5"
1181 bendDielectricFile = prepareHDF5File(bendFnEps)
1182 bendField.output_hdf5(Dielectric, bendVol.surroundings(), bendDielectricFile)
1183
1184 #create the file for the field components
1185 bendFileOutputEz = prepareHDF5File(bendFnEz)
1186
1187 #define the flux plane for the reflected flux
1188 bendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
1189 bendReflectedFluxPlane = volume(vec(bendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(bendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
1190 bendReflectedFlux = bendField.add_dft_flux_plane(bendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
1191
1192 #load the minused reflection flux from the "no bend" case as initalization
1193 bendReflectedFlux.load_hdf5(bendField, "minusflux")
1194
1195
1196 #define the flux plane for the transmitted flux
1197 bendTransmfluxPlaneYPos = padSize + wgLengthY - 1.5; #the Y-coordinate of our transmission flux plane
1198 bendTransmFluxPlane = volume(vec(wgVerXCen - wgWidth,bendTransmfluxPlaneYPos),vec(wgVerXCen + wgWidth,bendTransmfluxPlaneYPos))
1199 bendTransmFlux = bendField.add_dft_flux_plane(bendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
1200
1201 master_printf("Calculating...")
1202 bendProbingpoint = vec(wgVerXCen,bendTransmfluxPlaneYPos) #the point at the end of the waveguide that we want to probe to check if source has decayed
1203 runUntilFieldsDecayed(bendField, bendVol, srcComp, bendProbingpoint, bendFileOutputEz)
1204 master_printf("Done..!")
1205
1206 #construct 2-dimensional array with the flux plane data
1207 #see python_meep.py
1208 bendReflFlux = getFluxData(bendReflectedFlux)
1209 bendTransmFlux = getFluxData(bendTransmFlux)
1210
1211 del_EPS_Callback()
1212
1213 #SHOW THE RESULTS IN A PLOT
1214 frequencies = bendReflFlux[0] #should be equal to bendTransmFlux.keys() or noBendTransmFlux.keys() or ...
1215 Ptrans = [x / y for x,y in zip(bendTransmFlux[1], noBendTransmFlux[1])]
1216 Prefl = [ abs(x / y) for x,y in zip(bendReflFlux[1], noBendTransmFlux[1]) ]
1217 Ploss = [ 1-x-y for x,y in zip(Ptrans, Prefl)]
1218
1219 matplotlib.pyplot.plot(frequencies, Ptrans, 'bo')
1220 matplotlib.pyplot.plot(frequencies, Prefl, 'ro')
1221 matplotlib.pyplot.plot(frequencies, Ploss, 'go' )
1222
1223 matplotlib.pyplot.show()
1224
1225
1226
1227**9. Running in MPI mode (multiprocessor configuration)**
1228----------------------------------------------------------
1229
1230* We assume that an MPI implementation is installed on your machine (e.g. OpenMPI).
1231If you want to run python-meep in MPI mode, then you must must import the ``meep_mpi`` module instead of the ``meep`` module :
1232
1233``from meep_mpi import *``
1234
1235Then start up the Python script as follows :
1236
1237``mpirun -n 2 ./myscript.py``
1238
1239The ``-n`` parameter indicates the number of processors requested.
1240
1241* For printing output to the console, use the ``master_printf`` statement. This will generate output on the master node only (regular Python ``print`` statements will run on all nodes).
1242
1243* If you output HDF5 files, make sure your HDF5 library is MPI-enable, otherwise your Python script will stall upon writing HDF5 due to a deadlock.
1244
1245
1246
1247**10. Differences between Python-Meep and Scheme-Meep (libctl)**
1248------------------------------------------------------------------
1249
1250**note**: this section does NOT apply to the UGent Intec Photonics Research Group (apart from the coordinate system, the default behaviour for us is made consistent with Scheme-Meep)
1251
1252The general rule is that Python-Meep has consistent behaviour with the **C++ core of Meep**.
1253The default version of Python-Meep (compiled from the LATEST_RELEASE branch) has 3 differences compared with the Scheme version of Meep :
1254 * in Python-meep, the center of the coordinate system is in the upper left corner (in Scheme-Meep v1.1.1, the center of the coordinate system is in the middle of your computational volume).
1255 * in Python-meep, eps-averaging is disabled by default (see section 3.2 for details on how to enable eps-averaging)
1256 * in Python-meep, calculation is done with complex fields by default (in Scheme-Meep v1.1.1, real fields are used by default). You can call function use_real_fields() on your fields-object to enable calculation with real fields only.
1257
1258On starting your script, Python-Meep will warn you about these differences. You can suppress these warning by setting the global variables ``DISABLE_WARNING_COORDINATESYSTEM``, ``DISABLE_WARNING_EPS_AVERAGING`` and ``DISABLE_WARNING_REAL_FIELDS`` to ``True``. You can add site-specific customisations to the file ``meep-site-init.py`` : in this script, you can for example suppress the warning, or enable EPS-averaging by default.
1259
1260Add the following code to ``meep-site-init.py`` if you want *to calculate with real fields only by default* :
1261
1262::
1263
1264 #by default enable calculation with real fields only (consistent with Scheme-meep)
1265 def fields(structure, m = 0, store_pol_energy=0):
1266 f = fields_orig(structure, m, store_pol_energy)
1267 f.use_real_fields()
1268 return f
1269
1270 #add a new construct 'fields_complex' that you can use to force calculation with complex fields
1271 def fields_complex(structure, m = 0, store_pol_energy=0):
1272 master_printf("Calculation with complex fields enalbed.\n")
1273 return fields_orig(structure, m, store_pol_energy)
1274
1275 global DISABLE_WARNING_REAL_FIELDS
1276 DISABLE_WARNING_REAL_FIELDS = True
1277
1278
1279Add the following code to ``meep-site-init.py`` if you want *to enable EPS-averaging by default* :
1280
1281::
1282
1283 use_averaging(True)
1284
1285 global DISABLE_WARNING_EPS_AVERAGING
1286 DISABLE_WARNING_EPS_AVERAGING = True
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
01300
=== added file 'doc/html/.buildinfo'
--- doc/html/.buildinfo 1970-01-01 00:00:00 +0000
+++ doc/html/.buildinfo 2009-12-01 14:23:09 +0000
@@ -0,0 +1,4 @@
1# Sphinx build info version 1
2# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
3config: be01740a8ae8c3dde5cf900e473f3548
4tags: fbb0d17656682115ca4d033fb2f83ba1
05
=== added directory 'doc/html/_images'
=== added file 'doc/html/_images/bentwgB.gif'
1Binary files doc/html/_images/bentwgB.gif 1970-01-01 00:00:00 +0000 and doc/html/_images/bentwgB.gif 2009-12-01 14:23:10 +0000 differ6Binary files doc/html/_images/bentwgB.gif 1970-01-01 00:00:00 +0000 and doc/html/_images/bentwgB.gif 2009-12-01 14:23:10 +0000 differ
=== added file 'doc/html/_images/bentwgNB.gif'
2Binary files doc/html/_images/bentwgNB.gif 1970-01-01 00:00:00 +0000 and doc/html/_images/bentwgNB.gif 2009-12-01 14:23:10 +0000 differ7Binary files doc/html/_images/bentwgNB.gif 1970-01-01 00:00:00 +0000 and doc/html/_images/bentwgNB.gif 2009-12-01 14:23:10 +0000 differ
=== added file 'doc/html/_images/fluxes.png'
3Binary files doc/html/_images/fluxes.png 1970-01-01 00:00:00 +0000 and doc/html/_images/fluxes.png 2009-12-01 14:23:10 +0000 differ8Binary files doc/html/_images/fluxes.png 1970-01-01 00:00:00 +0000 and doc/html/_images/fluxes.png 2009-12-01 14:23:10 +0000 differ
=== added directory 'doc/html/_sources'
=== added directory 'doc/html/_sources/.svn'
=== added file 'doc/html/_sources/.svn/all-wcprops'
--- doc/html/_sources/.svn/all-wcprops 1970-01-01 00:00:00 +0000
+++ doc/html/_sources/.svn/all-wcprops 2009-12-01 14:23:10 +0000
@@ -0,0 +1,11 @@
1K 25
2svn:wc:ra_dav:version-url
3V 59
4/svn/python-meep/!svn/ver/44/trunk/doc/_build/html/_sources
5END
6python_meep_documentation.txt
7K 25
8svn:wc:ra_dav:version-url
9V 89
10/svn/python-meep/!svn/ver/70/trunk/doc/_build/html/_sources/python_meep_documentation.txt
11END
012
=== added file 'doc/html/_sources/.svn/entries'
--- doc/html/_sources/.svn/entries 1970-01-01 00:00:00 +0000
+++ doc/html/_sources/.svn/entries 2009-12-01 14:23:10 +0000
@@ -0,0 +1,62 @@
19
2
3dir
444
5http://zita.intec.ugent.be/svn/python-meep/trunk/doc/_build/html/_sources
6http://zita.intec.ugent.be/svn/python-meep
7
8
9
102009-10-19T12:09:25.091644Z
1144
12elambert
13
14
15svn:special svn:externals svn:needs-lock
16
17
18
19
20
21
22
23
24
25
26
27556452f8-113f-44a6-93c3-95c7ba0365e5
28
029
30python_meep_documentation.txt
31file
3270
33
34
35
362009-12-01T08:16:44.000000Z
376d3942cec680bab591d7645d0696ea53
382009-12-01T08:17:30.437718Z
3970
40elambert
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
6255924
63
164
265
=== added file 'doc/html/_sources/.svn/format'
--- doc/html/_sources/.svn/format 1970-01-01 00:00:00 +0000
+++ doc/html/_sources/.svn/format 2009-12-01 14:23:10 +0000
@@ -0,0 +1,1 @@
19
02
=== added directory 'doc/html/_sources/.svn/prop-base'
=== added directory 'doc/html/_sources/.svn/props'
=== added directory 'doc/html/_sources/.svn/text-base'
=== added file 'doc/html/_sources/.svn/text-base/python_meep_documentation.txt.svn-base'
--- doc/html/_sources/.svn/text-base/python_meep_documentation.txt.svn-base 1970-01-01 00:00:00 +0000
+++ doc/html/_sources/.svn/text-base/python_meep_documentation.txt.svn-base 2009-12-01 14:23:10 +0000
@@ -0,0 +1,1293 @@
1PYTHON-MEEP BINDING DOCUMENTATION
2====================================
3
4Primary author of this documentation : EL : Emmanuel.Lambert@intec.ugent.be
5
6Document history :
7
8::
9
10 * EL-19/20/21-08-2009 : document creation
11 * EL-24-08-2009 : small improvements & clarifications.
12 * EL-25/26-08-2009 : sections 7 & 8 were added.
13 * EL-03-04/09/2009 :
14 -class "structure_eps_pml" (removed again in v0.8).
15 -port to Meep 1.1.1 (class 'volume' was renamed to 'grid_volume' and class 'geometric_volume' to 'volume'
16 -minor changes in the bent waveguide sample, to make it more consistent with the Scheme version
17 * EL-07-08/09/2009 : sections 3.2, 8.2, 8.3 : defining a material function with inline C/C++
18 * EL-10/09/2009 : additions for MPI mode (multiprocessor)
19 * EL-21/10/2009 : amplitude factor callback function
20 * EL-22/10/2009 : keyword arguments for runUntilFieldsDecayed
21 * EL-01/12/2009 : alignment with version 0.8 - III
22
23
24
25**1. The general structure of a python-meep program**
26-----------------------------------------------------
27
28In general terms, a python-meep program can be structured as follows :
29
30 * import the python-meep binding :
31 ``from meep import *``
32 This will load the library ``_meep.so`` and Python-files ``meep.py`` and ``python_meep.py`` from path ``/usr/local/lib/python2.6/dist-packages/``
33
34 If you are running in MPI mode (multiprocessor, see section 9), then you have to import module ``meep_mpi`` instead :
35 ``from meep_mpi import *``
36
37 * define a computational grid volume
38 See section 2 below which explains usage of the ``grid_volume`` class.
39
40 * define the waveguide structure (describing the geometry, PML and materials)
41 See section 3 below which explains usage of the ``structure`` class.
42
43 * create an object which will hold the calculated fields
44 See section 4 below which explains usage of the ``field`` class.
45
46 * define the sources
47 See section 5 below which explains usage of the ``add_point_source`` and ``add_volume_source`` functions.
48
49 * run the simulation (iterate over the time-steps)
50 See section 6 below.
51
52Section 7 gives details about defining and retrieving fluxes.
53
54Section 9 gives some complete examples.
55
56Section 10 outlines some differences between Scheme-Meep and Python-Meep.
57
58
59**2. Defining the computational grid volume**
60---------------------------------------------
61
62The following set of 'factory functions' is provided, aimed at creating a ``grid_volume`` object. The first arguments define the size of the computational volume, the last argument is the computational grid resolution (in pixels per distance unit).
63 * ``volcyl(rsize, zsize, resolution)``
64 Defines a cyclical computational grid volume.
65 * ``volone(zsize, resolution)`` *alternatively called* ``vol1d(zsize, resolution)``
66 Defines a 1-dimensional computational grid volume along the Z-axis.
67 * ``voltwo(xsize, ysize, resolution)`` *alternatively called* ``vol2d(xsize, ysize, a)``
68 Defines a 2-dimensional computational grid volumes along the X- and Y-axes
69 * ``vol3d(xsize, ysize, zsize, resolution)``
70 Defines a 3-dimensional computational grid volume.
71
72 e.g.: ``v = volone(6, 10)`` defines a 1-dimensional computational volume of lenght 6, with 10 pixels per distance unit.
73
74
75**3. Defining the waveguide structure**
76---------------------------------------
77
78The waveguide structure is defined using the class ``structure``, of which the constructor has the following arguments :
79
80 * *required* : the computational grid volume (a reference to an object of type ``grid_volume``, see section 2 above)
81
82 * *required* : a function defining the dielectric properties of the materials in the computational grid volume (thus describing the actual waveguide structure). For all-air, the predefined function 'one' can be used (epsilon = constant value 1). See note 3.1 below for more information about defining your own custom material function.
83
84 * *optional* : a boundary region: this is a reference to an object of type ``boundary_region``. There are a number of predefined functions that can be used to create such an object :
85 - ``no_pml()`` describing a conditionless boundary region (no PML)
86 - ``pml(thickness)`` : decribing a perfectly matching layer (PML) of a certain thickness (double value) on the boundaries in all directions.
87 - ``pml(thickness, direction)`` : decribing a perfectly matching layer (PML) of a certain thickness (double value) in a certain direction (``X, Y, Z, R or P``).
88 - ``pml(thickness, direction, boundary_side)`` : describing a PML of a certain thickness (double value), in a certain direction (``X, Y, Z, R or P``) and on the ``High`` or ``Low`` side. E.g. if boundary_side is ``Low`` and direction is ``X``, then a PML layer is added to the −x boundary. The default puts PML layers on both sides of the direction.
89
90 * *optional* : a function defining a symmetry to exploit, in order to speed up the FDTD calculation (reference to an object of type ``symmetry``). The following predefined functions can be used to create a ``symmetry`` object:
91 - ``identity`` : no symmetry
92 - ``rotate4(direction, grid_volume)`` : defines a 90° rotational symmetry with 'direction' the axis of rotation.
93 - ``rotate2(direction, grid_volume)`` : defines a 180° rotational symmetry with 'direction' the axis of rotation.
94 - ``mirror(direction, grid_volume)`` : defines a mirror symmetry plane with 'direction' normal to the mirror plane.
95 - ``r_to_minus_r_symmetry`` : defines a mirror symmetry in polar coordinates
96
97 * optional: the number of chunks in which to split up the calculated geometry. If you leave this empty, it is auto-configured. Otherwise, you would set this to a factor which is a multiple of the number of processors in your MPI run (for multiprocessor configuration).
98
99 e.g. : if ``v`` is a variable pointing to the computational grid volume, then :
100 ``s = structure(v, one)`` defines a structure with all air (eps=1),
101 which is equivalent to:
102 ``s = structure(v, one, no_pml(), identity(), 1)``
103
104 Another example : ``s = structure(v, EPS, pml(0.1,Y) )`` with EPS a custom material function, which is explained in the note below.
105
106
1073.1. Defining a material function
108________________________________________
109
110In order to describe the geometry of the waveguide, we have to provide a 'material function' returning the dielectric variable epsilon as a function of the position (identified by a vector). In python-meep, we can do this by defining a class that inherits from class ``Callback``. Through this inheritance, the core meep library (written in C++) will be able to call back to the Python function which describes the material properties.
111It is also possible (and faster) to write your material function in inline C/C++ (see 3.3)
112
113E.g. :
114
115::
116
117 class epsilon(Callback): #inherit from Callback for integration with the meep core library
118 def __init__(self):
119 Callback.__init__(self)
120 def double_vec(self,vec): #override of function in the Callback class to set the eps function
121 self.set_double(self.eps(vec))
122 return
123 def eps(self,vec): #return the epsilon value for a certain point (indicated by the vector v)
124 v = vec
125 r = v.x()*v.x() + v.y()*v.y()
126 dr = sqrt(r)
127 while dr>1:
128 dr-=1
129 if dr > 0.7001:
130 return 12.0
131 return 1.0
132
133Please note the **brackets** when referring to the x- and y-components of the vector ``vec``. These are **crucial** : no error message will be thrown if you refer to it as vec.x or vec.y, but the value will always be zero.
134So, one should write : ``vec.x()`` and ``vec.y()``.
135
136The meep-python library has a 'global' variable EPS, which is used as a reference for communication between the Meep core library and the Python code. We assign our epsilon-function as follows to the global EPS variable :
137
138::
139
140 set_EPS_Callback(epsilon().__disown__())
141 s = structure(v, EPS, no_pml(), identity())
142
143
144The call to function ``__disown__()`` is for memory management purposes and is *absolutely required*. An improvement of the python-meep binding could consist of making this call transparant for the end user. But for now, the user must manually provide it.
145
146***Important remark*** : at the end of our program, we should call : ``del_EPS_Callback()`` in order to clean up the global variable.
147
148For better performance, you can define your EPS material function with inline C/C++ : we refer to section 3.3 for details about this.
149
1503.2 Eps-averaging
151_________________
152
153EPS-averaging (anisotrpic averaging) is disabled by default, making this behaviour consistent with the behaviour of the Meep C++ core.
154
155You can enable EPS-averaging using the function ``use_averaging`` :
156
157::
158
159 #enable EPS-averaging
160 use_averaging(True)
161 ...
162 #disable EPS-averaging
163 use_averaging(False)
164 ...
165
166
167Enabling EPS-averaging results in slower performance, but more accurate results.
168
169
1703.3. Defining a material function with inline C/C++
171_________________________________________________________
172
173The approach described in 3.1 lets the Meep core library call back to Python for every query of the epsilon-function. This creates a lot of overhead.
174An approach which has a lot better performance is to define this epsilon-function with an inline C-function or C++ class.
175
176* If our epsilon-function needs *no other parameters than the position vector (X, Y, Z)*, then we can suffice with an inline C-function (the geometry dependencies are then typically hardcoded).
177
178* If our epsilon-function needs to base it's calculation on *a more complex set of parameters (e.g. parameters depending on the geometry)*, then we have to write a C++ class.
179
180For example, in the bent-waveguide example (section 8.3), we can define a generic C++ class which can return the epsilon-value for both the "bend" and "no bend" case, with variable size parameters.
181We can also take a simpler approach (section 8.2) and write a function in which the geometry size parameters are hardcoded : we then need 2 inline C-functions : one for the "bend" case and one for the "no bend" case.
182
183
1843.3.1 Inline C-function
185.......................
186
187First we create a header file, e.g. "eps_function.hpp" which contains our EPS-function.
188Not that the geometry dependencies are hardcoded (``upperLimitHorizontalWg = 4`` and ``lowerLimitHorizontalWg = 5``).
189
190::
191
192
193 namespace meep
194 {
195 static double myEps(const vec &v) {
196 double xCo = v.x();
197 double yCo = v.y();
198 double upperLimitHorizontalWg = 4;
199 double lowerLimitHorizontalWg = 5;
200 if ((yCo < upperLimitHorizontalWg) || (yCo > lowerLimitHorizontalWg)){
201 return 1.0;
202 }
203 else return 12.0;
204 }
205 }
206
207
208Then, in the Python program, we prepare and set the callback function as shown below.
209``prepareCallbackCfunction`` returns a pointer to the C-function, which we deliver to the Meep core using ``set_EPS_CallbackInlineFunction``.
210
211::
212
213 def initEPS(isWgBent):
214 funPtr = prepareCallbackCfunction("myEps","eps_function.hpp") #name of your function / name of header file
215 set_EPS_CallbackInlineFunction(funPtr)
216 print "EPS function successfully set."
217 return funPtr
218
219We refer to section 8.2 below for a full example.
220
221
2223.3.2 Inline C++-class
223......................
224
225A more complex approach is to have a C++ object that can accept more parameters when it is constructed.
226For example this is the case if want to change the parameters of the geometry from inside Python without touching the C++ code.
227
228We create a header file "eps_class.hpp" which contains the definition of the class (the class must inherit from ``Callback``).
229In the example below, the parameters ``upperLimitHorizontalWg`` and ``widthWg`` will be communicated from Python upon construction of the object.
230If these parameters then change (depending on the geometry), the C++ object will follow automatically.
231
232
233::
234
235 using namespace meep;
236
237 namespace meep
238 {
239
240 class myEpsCallBack : virtual public Callback {
241
242 public:
243 myEpsCallBack() : Callback() { };
244 ~myEpsCallBack() { cout << "Callback object destructed." << endl; };
245
246 myEpsCallBack(double upperLimitHorizontalWg, double widthWg) : Callback() {
247 _upperLimitHorizontalWg = upperLimitHorizontalWg;
248 _widthWg = widthWg;
249 };
250
251 double double_vec(const vec &v) { //return the EPS-value, depending on the position vector
252 double eps = myEps(v, _upperLimitHorizontalWg, _widthWg);
253 return eps;
254 };
255
256 complex<double> complex_vec(const vec &x) { return 0; }; //no need to implement
257 complex<double> complex_time(double &t) { return 0; }; //no need to implement //-->> SUBJECT TO CHANGE - in Intec branch of v0.8, this is complex_time(double t)
258
259
260 private:
261 double _upperLimitHorizontalWg;
262 double _widthWg;
263
264 double myEps(const vec &v, double upperLimitHorizontalWg, double widthWg) {
265 double xCo = v.x();
266 double yCo = v.y();
267 if ((yCo < upperLimitHorizontalWg) || (yCo > upperLimitHorizontalWg+widthWg)){
268 return 1.0;
269 }
270 }
271 return 12.0;
272 }
273
274 };
275
276 }
277
278
279The syntax in Python is a little bit more complex in this case.
280
281We will need to import the module ``scipy.weave`` :
282
283``from scipy.weave import *``
284
285(this is not required for the previous case of a simple inline function)
286
287First we create a list with the names of the parameters that we want to pass to the C++ class. These variables must be declared in the scope where the ``inline`` function call happens (see below).
288
289``c_params = ['upperLimitHorizontalWg','widthWg']``
290
291Then, we prepare the code snippet, using the function ``prepareCallbackCObjectCode`` and passing the class name and parameter names list.
292
293``c_code = prepareCallbackCObjectCode("myEpsCallBack", c_params)``
294
295Finally, we call the ``inline`` function, passing :
296 * the code snippet
297 * the list of parameter names
298 * the inline libraries, include directories and headers (helper functions are provided for this, see below). The call to ``getInlineHeaders`` should receive the name of the header file (with the definition of the C++ class) as an argument.
299
300``funPtr = inline(c_code,c_params, libraries=getInlineLibraries(), include_dirs = getInlineInclude(), headers = getInlineHeaders("eps_class.hpp") )``
301
302::
303
304
305 def initEPS():
306 #the set of parameters that we want to pass to the Callback object upon construction
307 #all these variables must be declared in the scope where the "inline" function call happens
308 c_params = ['upperLimitHorizontalWg','widthWg']
309 #the C-code snippet for constructing the Callback object
310 c_code = prepareCallbackCObjectCode("myEpsCallBack", c_params)
311 #do the actual inline C-call and fetch the pointer to the Callback object
312 funPtr = inline(c_code,c_params, libraries=getInlineLibraries(), include_dirs = getInlineInclude(), headers = getInlineHeaders("eps_class.hpp") )
313 #set the pointer to the callback object in the Python-meep core
314 set_EPS_CallbackInlineObject(funPtr)
315 print "EPS function successfully set."
316 return
317
318
319We refer to section 8.3 below for a full example.
320
321
322
323**4. Defining the initial field**
324---------------------------------
325
326This is optional.
327
328We create an object of type ``fields``, which will contain the calculated field.
329
330We must first create a Python class that inherits from class ``Callback`` and that will define the function for initialization of the field. Inheritance from class ``Callback`` is required, because the core meep library (written in C++) will have to call back to the Python function. For example, let's call our initialization class ``fi``.
331
332::
333
334 class fi(Callback): #inherit from Callback for integration with the meep core library
335 def __init__(self):
336 Callback.__init__(self)
337 def complex_vec(self,v): #override of function in the Callback class to set the field initialization function
338 #return the field value for a certain point (indicated by the vector v)
339 return complex(1.0,0)
340
341The meep-python library has a 'global' variable INIF, that is used to bind the meep core library to our Python field initialization class. To set INIF, we have to use the following statement :
342
343 ``set_INIF_Callback(fi().__disown__()) #link the INIF variable to the fi class``
344
345We refer to section 3-note1 for more information about the function ``__disown__()``.
346
347E.g.: If ``s`` is a variable pointing to the structure and ``comp`` denotes the component which we are initializing, then the complete field initialization code looks as follows :
348
349::
350
351 f = fields(s)
352 comp = Hy
353 f.initialize_field(comp, INIF)
354
355
356***Important remark*** : at the end of our program, we should then call : ``del_INIF_Callback()`` in order to clean up the global variable.
357
358The call to ``initialize_field`` is not mandatory. If the initial conditions are zeros for all components, then we can rely on the automatic initialization at creation of the object.
359
360We can additionally define **Bloch-periodic boundary conditions** over the field. This is done with the ``use_bloch`` function of the field class, e.g. :
361
362 ``f.use_bloch(vec(0.0))``
363
364*to be further elaborated - what is the exact meaning of the vector argument? (not well understood at this time)*
365
366
367
368**5. Defining the sources**
369---------------------------
370
371The definition of the current sources can be done through 2 functions of the ``fields`` class :
372 * ``add_point_source(component, src_time, vec, complex)``
373 * ``add_volume_source(component, src_time, volume, complex)``
374
375
376Each require as arguments an electromagnetic component (e.g. ``Ex, Ey, ...`` and ``Hx, Hy, ...``) and an object of type ``src_time``, which specifies the time dependence of the source (see below).
377
378For a point source, we must specify the center point of the current source using a vector (object of type ``vec``).
379
380For a volume source, we must specify an object of type ``volume`` (*to be elablorated*).
381
382The last argument is an overall complex amplitude number, multiplying the current source (default 1.0).
383
384The following variants are available :
385 * ``add_point_source(component, double, double, double, double, vec centerpoint, complex amplitude, int is_continuous)``
386 * This is a shortcut function so that no ``src_time`` object must be created. *This function is preferably used for point sources.*
387 * The four real arguments define the central frequency, spectral width, peaktime and cutoff.
388
389 * ``add_volume_source(component, src_time, volume)``
390
391 * ``add_volume_source(component, src_time, volume, AMPL)``
392 * AMPL is a built-in reference to a callback function. Such a callback function returns a factor to multiply the source amplitude with (complex value). It receives 1 parameter, i.e. a vector indicating a position RELATIVE to the CENTER of the source. See the example below.
393
394
395Three classes, inheriting from ``src_time``, are predefined and can be used off the shelf :
396 * ``gaussian_src_time`` for a Gaussian-pulse source. The constructor demands 2 arguments of type double :
397 * the center frequency ω, in units of 2πc
398 * the frequency width w used in the Gaussian
399 * ``continuous_src_time`` for a continuous-wave source proportional to exp(−iωt). The constructor demands 4 arguments :
400 * the frequency ω, in units 2πc/distance (complex number)
401 * the temporal width of smoothing (default 0)
402 * the start time (default 0)
403 * the end time (default infinity = never turn off)
404 * ``custom_src_time`` for a user-specified source function f(t) with start/end times. The constructor demands 4 arguments :
405 * The function f(t) specifying the time-dependence of the source
406 * *...(2nd argument unclear, to be further elaborated)...*
407 * the start time of the source (default -infinity)
408 * the end time of the source (default +infinity)
409
410For example, in order to define a continuous line source of length 1, from point (6,3) to point (6,4) in 2-dimensional geometry :
411
412::
413
414 #define a continuous source
415 srcFreq = 0.125
416 srcWidth = 20
417 src = continuous_src_time(srcFreq, srcWidth, 0, infinity)
418 srcComp = Ez
419 #make it a line source of size 1 starting on position(6,3)
420 srcGeo = volume(vec(6,3),vec(6,4))
421 f.add_volume_source(srcComp, src, srcGeo)
422
423
424Here is an example of the implementation of a callback function for the amplitude factor :
425
426::
427
428 class amplitudeFactor(Callback):
429 def __init__(self):
430 Callback.__init__(self)
431 master_printf("Callback function for amplitude factor activated.\n")
432
433 def complex_vec(self,vec):
434 #BEWARE, these are coordinates RELATIVE to the source center !!!!
435 x = vec.x()
436 y = vec.y()
437 master_printf("Fetching amplitude factor for x=%f - y=%f\n" %(x,y) )
438 result = complex(1.0,0)
439 return result
440
441 ...
442 #define a continuous source
443 srcFreq = 0.125
444 srcWidth = 20
445 src = continuous_src_time(srcFreq, srcWidth, 0, infinity)
446 srcComp = Ez
447 #make it a line source of size 1 starting on position(6,3)
448 srcGeo = volume(vec(6,3),vec(6,4))
449 #create callback object for amplitude factor
450 af = amplitudeFactor()
451 set_AMPL_Callback(af.__disown__())
452 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, AMPL)
453
454
455**6. Running the simulation, retrieving field values and exporting HDF5 files**
456-------------------------------------------------------------------------------
457
458We can now time-step and retrieve various field values along the way.
459The actual time step value can be retrieved or set through the variable ``f.dt``.
460
461The default time step in Meep is : ``Courant factor / resolution`` (in FDTD, the Courant factor relates the time step size to the spatial discretization: cΔt = SΔx. Default for S is 0.5). If no further parametrization is done, then this default value is used.
462
463To trigger a step in time, you call the function ``f.step()``.
464
465To step until the source has fully decayed :
466
467::
468
469 while (f.time() < f.last_source_time()):
470 f.step()
471
472The function ``runUntilFieldsDecayed`` mimicks the behaviour of 'stop-when-fields-decayed' in Meep-Scheme.
473This will run time steps until the source has decayed to 0.001 of the peak amplitude. After that, by default an additional 50 time steps will be run.
474The function has 7 arguments, of which 4 are mandatory and 3 are optional keywords arguments :
475* 4 regular arguments : reference to the field, reference to the computational grid volume, the source component, the monitor point.
476* keyword argument ``pHDF5OutputFile`` : reference to a HDF5 file (constructed with the function ``prepareHDF5File``); default : None (no ouput to files)
477* keyword argument ``pH5OutputIntervalSteps`` : step interval for output to HDF5 (default : 50)
478* keyword argument ``pDecayedStopAfterSteps`` : the number of steps to continue after the source has decayed to 0.001 of the peak amplitude at the probing point (default: 50)
479
480We further refer to section 8 below where this function is applied in an example.
481
482A rich functionality is available for retrieving field information. Some examples :
483
484 * ``f.energy_in_box(v.surroundings())``
485 * ``f.electric_energy_in_box(v.surroundings())``
486 * ``f.magnetic_energy_in_box(v.surroundings())``
487 * ``f.thermo_energy_in_box(v.surroundings())``
488 * ``f.total_energy()``
489 * ``f.field_energy_in_box(v.surroundings())``
490 * ``f.field_energy_in_box(component, v.surroundings())`` where the first argument is the electromagnetic component (``Ex, Ey, Ez, Er, Ep, Hx, Hy, Hz, Hr, Hp, Dx, Dy, Dz, Dp, Dr, Bx, By, Bz, Bp, Br, Dielectric`` or ``Permeability``)
491 * ``f.flux_in_box(X, v.surroundings())`` where the first argument is the direction (``X, Y, Z, R`` or ``P``)
492
493We can probe the field at certain points by defining a *monitor point* as follows :
494
495::
496
497 m = monitor_point()
498 p = vec(2.10) #vector identifying the point that we want to probe
499 f.get_point(m, p)
500 m.get_component(Hx)
501
502We can export the dielectric function and e.g. the Ex component of the field to HDF5 files as follows :
503
504::
505
506 #make sure you start your Python session with 'sudo' or write rights to the current path
507 feps = prepareHDF5File("eps.h5")
508 f.output_hdf5(Dielectric, v.surroundings(), feps) #export the Dielectric structure so that we can visually verify it
509 fex = prepareHDF5File("ex.h5")
510 while (f.time() < f.last_source_time()):
511 f.step()
512 f.output_hdf5(Ex, v.surroundings(), fex, 1) #export the Ex component, appending to the file "ex.h5"
513
514
515
516**7. Defining and retrieving fluxes**
517--------------------------------------
518
519First we define a flux plane.
520This is done through the creation of an object of type ``volume`` (specifying 2 vectors as arguments).
521
522Then we apply this flux plane to the field, specifying 4 parameters :
523 * the reference to the ``volume`` object
524 * the minimum frequency (in the example below, this is ``srcFreqCenter-(srcPulseWidth/2.0)``)
525 * the maximum frequency (in the example below this is ``srcFreqCenter+(srcPulseWidth/2.0)`` )
526 * the number of discrete frequencies that we want to monitor in the flux (in the example below, this is 100).
527
528After running the simulation, we can retrieve the flux values through the function ``getFluxData()`` : this returns a 2-dimensional array with the frequencies and actual flux values.
529
530E.g., if ``f`` is the field, then we proceed as follows :
531
532::
533
534 #define the flux plane and flux parameters
535 fluxplane = volume(vec(1,2),vec(1,3))
536 flux = f.add_dft_flux_plane(fluxplane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
537
538 #run the calculation
539 while (f.time() < f.last_source_time()):
540 f.step()
541
542 #retrieve the flux data
543 fluxdata = getFluxData(flux)
544 frequencies = fluxdata[0]
545 fluxvalues = fluxdata[1]
546
547
548
549**8. The "90 degree bent waveguide example in Python**
550------------------------------------------------------
551
552We have ported the "90 degree bent waveguide" example from the Meep-Scheme tutorial to Python.
553
554The original example can be found on the following URL : http://ab-initio.mit.edu/wiki/index.php/Meep_Tutorial
555(section 'A 90° bend').
556
557You can find the source code below and also in the ``/samples/bent_waveguide`` directory of the Python-Meep distribution.
558
559Sections 8.2 and 8.3 contain the same example but with the EPS-callback function as inline C-function and inline C++-class.
560
561The following animated gifs can be produced from the HDF5-files (see the script included in directory 'samples') :
562
563.. image:: images/bentwgNB.gif
564
565.. image:: images/bentwgB.gif
566
567
568And here is the graph of the transmission, reflection and loss fluxes, showing the same results as the example in Scheme:
569
570.. image:: images/fluxes.png
571 :height: 315
572 :width: 443
573
574
5758.1 With a Python class as EPS-function
576________________________________________
577
578
579A bottleneck in this version is the epsilon-function, which is written in Python.
580This means that the Meep core library must do a callback to the Python function, which creates a lot of overhead.
581An approach which has a much better performance is to write this EPS-function in C : the Meep core library can then directly call back to a C-function.
582These approaches are described in 8.2 and 8.3.
583
584::
585
586 from meep import *
587 from math import *
588 from python_meep import *
589 import numpy
590 import matplotlib.pyplot
591 import sys
592
593 res = 10.0
594 gridSizeX = 16.0
595 gridSizeY = 32.0
596 padSize = 4.0
597 wgLengthX = gridSizeX - padSize
598 wgLengthY = gridSizeY - padSize
599 wgWidth = 1.0 #width of the waveguide
600 wgHorYCen = padSize + wgWidth/2.0 #horizontal waveguide center Y-pos
601 wgVerXCen = wgLengthX - wgWidth/2.0 #vertical waveguide center X-pos (in case there is a bend)
602 srcFreqCenter = 0.15 #gaussian source center frequency
603 srcPulseWidth = 0.1 #gaussian source pulse width
604 srcComp = Ez #gaussian source component
605
606 #this function plots the waveguide material as a function of a vector(X,Y)
607 class epsilon(Callback):
608 def __init__(self, pIsWgBent):
609 Callback.__init__(self)
610 self.isWgBent = pIsWgBent
611 def double_vec(self,vec):
612 if (self.isWgBent): #there is a bend
613 if ((vec.x()<wgLengthX) and (vec.y() >= padSize) and (vec.y() <= padSize+wgWidth)):
614 return 12.0
615 elif ((vec.x()>=wgLengthX-wgWidth) and (vec.x()<=wgLengthX) and vec.y()>= padSize ):
616 return 12.0
617 else:
618 return 1.0
619 else: #there is no bend
620 if ((vec.y() >= padSize) and (vec.y() <= padSize+wgWidth)):
621 return 12.0
622 else:
623 return 1.0
624
625 def createField(pCompVol, pWgLengthX, pWgWidth, pIsWgBent, pSrcFreqCenter, pSrcPulseWidth, pSrcComp):
626 #we create a structure with PML of thickness = 1.0 on all boundaries,
627 #in all directions,
628 #using the material function EPS
629 material = epsilon(pIsWgBent)
630 set_EPS_Callback(material.__disown__())
631 s = structure(pCompVol, EPS, pml(1.0) )
632 f = fields(s)
633 #define a gaussian line source of length 'wgWidth' at X=wgLength/2, Y=padSize
634 srcGaussian = gaussian_src_time(pSrcFreqCenter, pSrcPulseWidth )
635 srcGeo = volume(vec(1.0,padSize),vec(1.0,padSize+pWgWidth))
636 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, 1)
637 print "Field created..."
638 return f
639
640
641 #FIRST WE WORK OUT THE CASE WITH NO BEND
642 #----------------------------------------------------------------
643 print "*1* Starting the case with no bend..."
644 #create the computational grid
645 noBendVol = voltwo(gridSizeX,gridSizeY,res)
646
647 #create the field
648 wgBent = 0 #no bend
649 noBendField = createField(noBendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
650
651 bendFnEps = "./bentwgNB_Eps.h5"
652 bendFnEz = "./bentwgNB_Ez.h5"
653 #export the dielectric structure (so that we can visually verify the waveguide structure)
654 noBendDielectricFile = prepareHDF5File(bendFnEps)
655 noBendField.output_hdf5(Dielectric, noBendVol.surroundings(), noBendDielectricFile)
656
657 #create the file for the field components
658 noBendFileOutputEz = prepareHDF5File(bendFnEz)
659
660 #define the flux plane for the reflected flux
661 noBendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
662 noBendReflectedFluxPlane = volume(vec(noBendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
663 noBendReflectedFlux = noBendField.add_dft_flux_plane(noBendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
664
665 #define the flux plane for the transmitted flux
666 noBendTransmfluxPlaneXPos = gridSizeX - 1.5; #the X-coordinate of our transmission flux plane
667 noBendTransmFluxPlane = volume(vec(noBendTransmfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendTransmfluxPlaneXPos,wgHorYCen+wgWidth))
668 noBendTransmFlux = noBendField.add_dft_flux_plane(noBendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
669
670 print "Calculating..."
671 noBendProbingpoint = vec(noBendTransmfluxPlaneXPos,wgHorYCen) #the point at the end of the waveguide that we want to probe to check if source has decayed
672 runUntilFieldsDecayed(noBendField, noBendVol, srcComp, noBendProbingpoint, noBendFileOutputEz)
673 print "Done..!"
674
675 #construct 2-dimensional array with the flux plane data
676 #see python_meep.py
677 noBendReflFlux = getFluxData(noBendReflectedFlux)
678 noBendTransmFlux = getFluxData(noBendTransmFlux)
679
680 #save the reflection flux from the "no bend" case as minus flux in the temporary file 'minusflux.h5'
681 noBendReflectedFlux.scale_dfts(-1);
682 f = open("minusflux.h5", 'w') #truncate file if already exists
683 f.close()
684 noBendReflectedFlux.save_hdf5(noBendField, "minusflux")
685
686 del_EPS_Callback()
687
688
689 #AND SECONDLY FOR THE CASE WITH BEND
690 #----------------------------------------------------------------
691 print "*2* Starting the case with bend..."
692 #create the computational grid
693 bendVol = voltwo(gridSizeX,gridSizeY,res)
694
695 #create the field
696 wgBent = 1 #there is a bend
697 bendField = createField(bendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
698
699 #export the dielectric structure (so that we can visually verify the waveguide structure)
700 bendFnEps = "./bentwgB_Eps.h5"
701 bendFnEz = "./bentwgB_Ez.h5"
702 bendDielectricFile = prepareHDF5File(bendFnEps)
703 bendField.output_hdf5(Dielectric, bendVol.surroundings(), bendDielectricFile)
704
705 #create the file for the field components
706 bendFileOutputEz = prepareHDF5File(bendFnEz)
707
708 #define the flux plane for the reflected flux
709 bendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
710 bendReflectedFluxPlane = volume(vec(bendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(bendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
711 bendReflectedFlux = bendField.add_dft_flux_plane(bendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
712
713 #load the minused reflection flux from the "no bend" case as initalization
714 bendReflectedFlux.load_hdf5(bendField, "minusflux")
715
716
717 #define the flux plane for the transmitted flux
718 bendTransmfluxPlaneYPos = padSize + wgLengthY - 1.5; #the Y-coordinate of our transmission flux plane
719 bendTransmFluxPlane = volume(vec(wgVerXCen - wgWidth,bendTransmfluxPlaneYPos),vec(wgVerXCen + wgWidth,bendTransmfluxPlaneYPos))
720 bendTransmFlux = bendField.add_dft_flux_plane(bendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
721
722 print "Calculating..."
723 bendProbingpoint = vec(wgVerXCen,bendTransmfluxPlaneYPos) #the point at the end of the waveguide that we want to probe to check if source has decayed
724 runUntilFieldsDecayed(bendField, bendVol, srcComp, bendProbingpoint, bendFileOutputEz)
725 print "Done..!"
726
727 #construct 2-dimensional array with the flux plane data
728 #see python_meep.py
729 bendReflFlux = getFluxData(bendReflectedFlux)
730 bendTransmFlux = getFluxData(bendTransmFlux)
731
732 del_EPS_Callback()
733
734 #SHOW THE RESULTS IN A PLOT
735 frequencies = bendReflFlux[0] #should be equal to bendTransmFlux.keys() or noBendTransmFlux.keys() or ...
736 Ptrans = [x / y for x,y in zip(bendTransmFlux[1], noBendTransmFlux[1])]
737 Prefl = [ abs(x / y) for x,y in zip(bendReflFlux[1], noBendTransmFlux[1]) ]
738 Ploss = [ 1-x-y for x,y in zip(Ptrans, Prefl)]
739
740 matplotlib.pyplot.plot(frequencies, Ptrans, 'bo')
741 matplotlib.pyplot.plot(frequencies, Prefl, 'ro')
742 matplotlib.pyplot.plot(frequencies, Ploss, 'go' )
743
744 matplotlib.pyplot.show()
745
746
7478.2 With an inline C-function as EPS-function
748______________________________________________
749
750The header file "eps_function.hpp" :
751
752::
753
754 using namespace meep;
755
756 namespace meep
757 {
758 static double myEps(const vec &v, bool isWgBent) {
759 double xCo = v.x();
760 double yCo = v.y();
761 double upperLimitHorizontalWg = 4;
762 double wgLengthX = 12;
763 double leftLimitVerticalWg = 11;
764 double lowerLimitHorizontalWg = 5;
765 if (isWgBent){ //there is a bend
766 if ((yCo < upperLimitHorizontalWg) || (xCo>wgLengthX)){
767 return 1.0;
768 }
769 else {
770 if ((xCo < leftLimitVerticalWg) && (yCo > lowerLimitHorizontalWg)) {
771 return 1.0;
772 }
773 else {
774 return 12.0;
775 }
776 }
777 }
778 else { //there is no bend
779 if ((yCo < upperLimitHorizontalWg) || (yCo > lowerLimitHorizontalWg)){
780 return 1.0;
781 }
782 }
783 return 12.0;
784 }
785
786 static double myEpsBentWg(const vec &v) {
787 return myEps(v, true);
788 }
789
790 static double myEpsStraightWg(const vec &v) {
791 return myEps(v, false);
792 }
793 }
794
795
796
797And the actual Python program :
798
799
800::
801
802
803 from meep import *
804
805 from math import *
806 import numpy
807 import matplotlib.pyplot
808 import sys
809
810 res = 10.0
811 gridSizeX = 16.0
812 gridSizeY = 32.0
813 padSize = 4.0
814 wgLengthX = gridSizeX - padSize
815 wgLengthY = gridSizeY - padSize
816 wgWidth = 1.0 #width of the waveguide
817 upperLimitHorizontalWg = padSize
818 lowerLimitHorizontalWg = padSize+wgWidth
819 leftLimitVerticalWg = wgLengthX-wgWidth
820 wgHorYCen = padSize + wgWidth/2.0 #horizontal waveguide center Y-pos
821 wgVerXCen = wgLengthX - wgWidth/2.0 #vertical waveguide center X-pos (in case there is a bend)
822 srcFreqCenter = 0.15 #gaussian source center frequency
823 srcPulseWidth = 0.1 #gaussian source pulse width
824 srcComp = Ez #gaussian source component
825
826 def initEPS(isWgBent):
827 if (isWgBent):
828 funPtr = prepareCallbackCfunction("myEpsBentWg","eps_function.hpp")
829 else:
830 funPtr = prepareCallbackCfunction("myEpsStraightWg","eps_function.hpp")
831 set_EPS_CallbackInlineFunction(funPtr)
832 print "EPS function successfully set."
833 return funPtr
834
835 def createField(pCompVol, pWgLengthX, pWgWidth, pIsWgBent, pSrcFreqCenter, pSrcPulseWidth, pSrcComp):
836 #we create a structure with PML of thickness = 1.0 on all boundaries,
837 #in all directions,
838 #using the material function EPS
839 s = structure(pCompVol, EPS, pml(1.0) )
840 f = fields(s)
841 #define a gaussian line source of length 'wgWidth' at X=wgLength/2, Y=padSize
842 srcGaussian = gaussian_src_time(pSrcFreqCenter, pSrcPulseWidth )
843 srcGeo = volume(vec(1.0,padSize),vec(1.0,padSize+pWgWidth))
844 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, 1)
845 print "Field created..."
846 return f
847
848
849 master_printf("BENT WAVEGUIDE SAMPLE WITH INLINE C-FUNCTION FOR EPS\n")
850
851 master_printf("Running on %d processor(s)...\n",count_processors())
852
853 #FIRST WE WORK OUT THE CASE WITH NO BEND
854 #----------------------------------------------------------------
855 master_printf("*1* Starting the case with no bend...")
856
857 #set EPS material function
858 initEPS(0)
859
860 #create the computational grid
861 noBendVol = voltwo(gridSizeX,gridSizeY,res)
862
863 #create the field
864 wgBent = 0 #no bend
865 noBendField = createField(noBendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
866
867 bendFnEps = "./bentwgNB_Eps.h5"
868 bendFnEz = "./bentwgNB_Ez.h5"
869 #export the dielectric structure (so that we can visually verify the waveguide structure)
870 noBendDielectricFile = prepareHDF5File(bendFnEps)
871 noBendField.output_hdf5(Dielectric, noBendVol.surroundings(), noBendDielectricFile)
872
873 #create the file for the field components
874 noBendFileOutputEz = prepareHDF5File(bendFnEz)
875
876 #define the flux plane for the reflected flux
877 noBendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
878 noBendReflectedFluxPlane = volume(vec(noBendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
879 noBendReflectedFlux = noBendField.add_dft_flux_plane(noBendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
880
881 #define the flux plane for the transmitted flux
882 noBendTransmfluxPlaneXPos = gridSizeX - 1.5; #the X-coordinate of our transmission flux plane
883 noBendTransmFluxPlane = volume(vec(noBendTransmfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendTransmfluxPlaneXPos,wgHorYCen+wgWidth))
884 noBendTransmFlux = noBendField.add_dft_flux_plane(noBendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
885
886 master_printf("Calculating...")
887 noBendProbingpoint = vec(noBendTransmfluxPlaneXPos,wgHorYCen) #the point at the end of the waveguide that we want to probe to check if source has decayed
888 runUntilFieldsDecayed(noBendField, noBendVol, srcComp, noBendProbingpoint, noBendFileOutputEz)
889 master_printf("Done..!")
890
891 #construct 2-dimensional array with the flux plane data
892 #see python_meep.py
893 noBendReflFlux = getFluxData(noBendReflectedFlux)
894 noBendTransmFlux = getFluxData(noBendTransmFlux)
895
896 #save the reflection flux from the "no bend" case as minus flux in the temporary file 'minusflux.h5'
897 noBendReflectedFlux.scale_dfts(-1);
898 f = open("minusflux.h5", 'w') #truncate file if already exists
899 f.close()
900 noBendReflectedFlux.save_hdf5(noBendField, "minusflux")
901
902 del_EPS_Callback() #destruct the inline-created object
903
904
905 #AND SECONDLY FOR THE CASE WITH BEND
906 #----------------------------------------------------------------
907 master_printf("*2* Starting the case with bend...")
908
909 #set EPS material function
910 initEPS(1)
911
912 #create the computational grid
913 bendVol = voltwo(gridSizeX,gridSizeY,res)
914
915 #create the field
916 wgBent = 1 #there is a bend
917 bendField = createField(bendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
918
919 #export the dielectric structure (so that we can visually verify the waveguide structure)
920 bendFnEps = "./bentwgB_Eps.h5"
921 bendFnEz = "./bentwgB_Ez.h5"
922 bendDielectricFile = prepareHDF5File(bendFnEps)
923 bendField.output_hdf5(Dielectric, bendVol.surroundings(), bendDielectricFile)
924
925 #create the file for the field components
926 bendFileOutputEz = prepareHDF5File(bendFnEz)
927
928 #define the flux plane for the reflected flux
929 bendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
930 bendReflectedFluxPlane = volume(vec(bendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(bendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
931 bendReflectedFlux = bendField.add_dft_flux_plane(bendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
932
933 #load the minused reflection flux from the "no bend" case as initalization
934 bendReflectedFlux.load_hdf5(bendField, "minusflux")
935
936
937 #define the flux plane for the transmitted flux
938 bendTransmfluxPlaneYPos = padSize + wgLengthY - 1.5; #the Y-coordinate of our transmission flux plane
939 bendTransmFluxPlane = volume(vec(wgVerXCen - wgWidth,bendTransmfluxPlaneYPos),vec(wgVerXCen + wgWidth,bendTransmfluxPlaneYPos))
940 bendTransmFlux = bendField.add_dft_flux_plane(bendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
941
942 master_printf("Calculating...")
943 bendProbingpoint = vec(wgVerXCen,bendTransmfluxPlaneYPos) #the point at the end of the waveguide that we want to probe to check if source has decayed
944 runUntilFieldsDecayed(bendField, bendVol, srcComp, bendProbingpoint, bendFileOutputEz)
945 master_printf("Done..!")
946
947 #construct 2-dimensional array with the flux plane data
948 #see python_meep.py
949 bendReflFlux = getFluxData(bendReflectedFlux)
950 bendTransmFlux = getFluxData(bendTransmFlux)
951
952 del_EPS_Callback()
953
954 #SHOW THE RESULTS IN A PLOT
955 frequencies = bendReflFlux[0] #should be equal to bendTransmFlux.keys() or noBendTransmFlux.keys() or ...
956 Ptrans = [x / y for x,y in zip(bendTransmFlux[1], noBendTransmFlux[1])]
957 Prefl = [ abs(x / y) for x,y in zip(bendReflFlux[1], noBendTransmFlux[1]) ]
958 Ploss = [ 1-x-y for x,y in zip(Ptrans, Prefl)]
959
960 matplotlib.pyplot.plot(frequencies, Ptrans, 'bo')
961 matplotlib.pyplot.plot(frequencies, Prefl, 'ro')
962 matplotlib.pyplot.plot(frequencies, Ploss, 'go' )
963
964 matplotlib.pyplot.show()
965
966
967
9688.3 With an inline C++ class as EPS-function
969______________________________________________
970
971
972The header file "eps_class.hpp" :
973
974
975::
976
977
978 using namespace meep;
979
980 namespace meep
981 {
982
983 class myEpsCallBack : virtual public Callback {
984
985 public:
986 myEpsCallBack() : Callback() { };
987 ~myEpsCallBack() { cout << "Callback object destructed." << endl; };
988
989 myEpsCallBack(bool isWgBent,double upperLimitHorizontalWg, double leftLimitVerticalWg, double lowerLimitHorizontalWg, double wgLengthX) : Callback() {
990 _IsWgBent = isWgBent;
991 _upperLimitHorizontalWg = upperLimitHorizontalWg;
992 _leftLimitVerticalWg = leftLimitVerticalWg;
993 _lowerLimitHorizontalWg = lowerLimitHorizontalWg;
994 _wgLengthX = wgLengthX;
995 };
996
997 double double_vec(const vec &v) {
998 double eps = myEps(v, _IsWgBent, _upperLimitHorizontalWg, _leftLimitVerticalWg, _lowerLimitHorizontalWg, _wgLengthX);
999 //cout << "X="<<v.x()<<"--Y="<<v.y()<<"--eps="<<eps<<"-"<<_upperLimitHorizontalWg<<"--"<<_leftLimitVerticalWg<<"--"<<_lowerLimitHorizontalWg<<"--"<<_wgLengthX;
1000 return eps;
1001 };
1002
1003 complex<double> complex_vec(const vec &x) { return 0; };
1004 complex<double> complex_time(double &t) { return 0; }; //-->> SUBJECT TO CHANGE - in Intec branch of v0.8, this is complex_time(double t)
1005
1006
1007 private:
1008 bool _IsWgBent;;
1009 double _upperLimitHorizontalWg;
1010 double _leftLimitVerticalWg;
1011 double _lowerLimitHorizontalWg;
1012 double _wgLengthX;
1013
1014 double myEps(const vec &v, bool isWgBent, double upperLimitHorizontalWg, double leftLimitVerticalWg, double lowerLimitHorizontalWg, double wgLengthX) {
1015 double xCo = v.x();
1016 double yCo = v.y();
1017 if (isWgBent){ //there is a bend
1018 if ((yCo < upperLimitHorizontalWg) || (xCo>wgLengthX)){
1019 return 1.0;
1020 }
1021 else {
1022 if ((xCo < leftLimitVerticalWg) && (yCo > lowerLimitHorizontalWg)) {
1023 return 1.0;
1024 }
1025 else {
1026 return 12.0;
1027 }
1028 }
1029 }
1030 else { //there is no bend
1031 if ((yCo < upperLimitHorizontalWg) || (yCo > lowerLimitHorizontalWg)){
1032 return 1.0;
1033 }
1034 }
1035 return 12.0;
1036 }
1037
1038 };
1039
1040 }
1041
1042
1043The Python program :
1044
1045
1046::
1047
1048
1049 from meep import *
1050
1051 from math import *
1052 import numpy
1053 import matplotlib.pyplot
1054 import sys
1055
1056 from scipy.weave import *
1057
1058 res = 10.0
1059 gridSizeX = 16.0
1060 gridSizeY = 32.0
1061 padSize = 4.0
1062 wgLengthX = gridSizeX - padSize
1063 wgLengthY = gridSizeY - padSize
1064 wgWidth = 1.0 #width of the waveguide
1065 upperLimitHorizontalWg = padSize
1066 lowerLimitHorizontalWg = padSize+wgWidth
1067 leftLimitVerticalWg = wgLengthX-wgWidth
1068 wgHorYCen = padSize + wgWidth/2.0 #horizontal waveguide center Y-pos
1069 wgVerXCen = wgLengthX - wgWidth/2.0 #vertical waveguide center X-pos (in case there is a bend)
1070 srcFreqCenter = 0.15 #gaussian source center frequency
1071 srcPulseWidth = 0.1 #gaussian source pulse width
1072 srcComp = Ez #gaussian source component
1073
1074
1075 def initEPS():
1076 #the set of parameters that we want to pass to the Callback object upon construction
1077 c_params = ['isWgBent','upperLimitHorizontalWg','leftLimitVerticalWg','lowerLimitHorizontalWg','wgLengthX'] #all these variables must be globally declared in the scope where the "inline" function call happens
1078 #the C-code snippet for constructing the Callback object
1079 c_code = prepareCallbackCObjectCode("myEpsCallBack", c_params)
1080 #do the actual inline C-call and fetch the pointer to the Callback object
1081 funPtr = inline(c_code,c_params, libraries=getInlineLibraries(), include_dirs = getInlineInclude(), headers = getInlineHeaders("eps_class.hpp") )
1082 #set the pointer to the callback object in the Python-meep core
1083 set_EPS_CallbackInlineObject(funPtr)
1084 print "EPS function successfully set."
1085 return
1086
1087 def createField(pCompVol, pWgLengthX, pWgWidth, pIsWgBent, pSrcFreqCenter, pSrcPulseWidth, pSrcComp):
1088 #we create a structure with PML of thickness = 1.0 on all boundaries,
1089 #in all directions,
1090 #using the material function EPS
1091 s = structure(pCompVol, EPS, pml(1.0) )
1092 f = fields(s)
1093 #define a gaussian line source of length 'wgWidth' at X=wgLength/2, Y=padSize
1094 srcGaussian = gaussian_src_time(pSrcFreqCenter, pSrcPulseWidth )
1095 srcGeo = volume(vec(1.0,padSize),vec(1.0,padSize+pWgWidth))
1096 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, 1)
1097 print "Field created..."
1098 return f
1099
1100 master_printf("BENT WAVEGUIDE SAMPLE WITH INLINE C++ CLASS FOR EPS\n")
1101
1102 master_printf("Running on %d processor(s)...\n",count_processors())
1103
1104 #FIRST WE WORK OUT THE CASE WITH NO BEND
1105 #----------------------------------------------------------------
1106 master_printf("*1* Starting the case with no bend...")
1107
1108 #set EPS material function
1109 isWgBent = 0
1110 initEPS()
1111
1112 #create the computational grid
1113 noBendVol = voltwo(gridSizeX,gridSizeY,res)
1114
1115 #create the field
1116 wgBent = 0 #no bend
1117 noBendField = createField(noBendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
1118
1119 bendFnEps = "./bentwgNB_Eps.h5"
1120 bendFnEz = "./bentwgNB_Ez.h5"
1121 #export the dielectric structure (so that we can visually verify the waveguide structure)
1122 noBendDielectricFile = prepareHDF5File(bendFnEps)
1123 noBendField.output_hdf5(Dielectric, noBendVol.surroundings(), noBendDielectricFile)
1124
1125 #create the file for the field components
1126 noBendFileOutputEz = prepareHDF5File(bendFnEz)
1127
1128 #define the flux plane for the reflected flux
1129 noBendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
1130 noBendReflectedFluxPlane = volume(vec(noBendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
1131 noBendReflectedFlux = noBendField.add_dft_flux_plane(noBendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
1132
1133 #define the flux plane for the transmitted flux
1134 noBendTransmfluxPlaneXPos = gridSizeX - 1.5; #the X-coordinate of our transmission flux plane
1135 noBendTransmFluxPlane = volume(vec(noBendTransmfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendTransmfluxPlaneXPos,wgHorYCen+wgWidth))
1136 noBendTransmFlux = noBendField.add_dft_flux_plane(noBendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
1137
1138 master_printf("Calculating...")
1139 noBendProbingpoint = vec(noBendTransmfluxPlaneXPos,wgHorYCen) #the point at the end of the waveguide that we want to probe to check if source has decayed
1140 runUntilFieldsDecayed(noBendField, noBendVol, srcComp, noBendProbingpoint, noBendFileOutputEz)
1141 master_printf("Done..!")
1142
1143 #construct 2-dimensional array with the flux plane data
1144 #see python_meep.py
1145 noBendReflFlux = getFluxData(noBendReflectedFlux)
1146 noBendTransmFlux = getFluxData(noBendTransmFlux)
1147
1148 #save the reflection flux from the "no bend" case as minus flux in the temporary file 'minusflux.h5'
1149 noBendReflectedFlux.scale_dfts(-1);
1150 f = open("minusflux.h5", 'w') #truncate file if already exists
1151 f.close()
1152 noBendReflectedFlux.save_hdf5(noBendField, "minusflux")
1153
1154 del_EPS_Callback() #destruct the inline-created object
1155
1156
1157 #AND SECONDLY FOR THE CASE WITH BEND
1158 #----------------------------------------------------------------
1159 master_printf("*2* Starting the case with bend...")
1160
1161 #set EPS material function
1162 isWgBent = 1
1163 initEPS()
1164
1165 #create the computational grid
1166 bendVol = voltwo(gridSizeX,gridSizeY,res)
1167
1168 #create the field
1169 wgBent = 1 #there is a bend
1170 bendField = createField(bendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
1171
1172 #export the dielectric structure (so that we can visually verify the waveguide structure)
1173 bendFnEps = "./bentwgB_Eps.h5"
1174 bendFnEz = "./bentwgB_Ez.h5"
1175 bendDielectricFile = prepareHDF5File(bendFnEps)
1176 bendField.output_hdf5(Dielectric, bendVol.surroundings(), bendDielectricFile)
1177
1178 #create the file for the field components
1179 bendFileOutputEz = prepareHDF5File(bendFnEz)
1180
1181 #define the flux plane for the reflected flux
1182 bendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
1183 bendReflectedFluxPlane = volume(vec(bendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(bendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
1184 bendReflectedFlux = bendField.add_dft_flux_plane(bendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
1185
1186 #load the minused reflection flux from the "no bend" case as initalization
1187 bendReflectedFlux.load_hdf5(bendField, "minusflux")
1188
1189
1190 #define the flux plane for the transmitted flux
1191 bendTransmfluxPlaneYPos = padSize + wgLengthY - 1.5; #the Y-coordinate of our transmission flux plane
1192 bendTransmFluxPlane = volume(vec(wgVerXCen - wgWidth,bendTransmfluxPlaneYPos),vec(wgVerXCen + wgWidth,bendTransmfluxPlaneYPos))
1193 bendTransmFlux = bendField.add_dft_flux_plane(bendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
1194
1195 master_printf("Calculating...")
1196 bendProbingpoint = vec(wgVerXCen,bendTransmfluxPlaneYPos) #the point at the end of the waveguide that we want to probe to check if source has decayed
1197 runUntilFieldsDecayed(bendField, bendVol, srcComp, bendProbingpoint, bendFileOutputEz)
1198 master_printf("Done..!")
1199
1200 #construct 2-dimensional array with the flux plane data
1201 #see python_meep.py
1202 bendReflFlux = getFluxData(bendReflectedFlux)
1203 bendTransmFlux = getFluxData(bendTransmFlux)
1204
1205 del_EPS_Callback()
1206
1207 #SHOW THE RESULTS IN A PLOT
1208 frequencies = bendReflFlux[0] #should be equal to bendTransmFlux.keys() or noBendTransmFlux.keys() or ...
1209 Ptrans = [x / y for x,y in zip(bendTransmFlux[1], noBendTransmFlux[1])]
1210 Prefl = [ abs(x / y) for x,y in zip(bendReflFlux[1], noBendTransmFlux[1]) ]
1211 Ploss = [ 1-x-y for x,y in zip(Ptrans, Prefl)]
1212
1213 matplotlib.pyplot.plot(frequencies, Ptrans, 'bo')
1214 matplotlib.pyplot.plot(frequencies, Prefl, 'ro')
1215 matplotlib.pyplot.plot(frequencies, Ploss, 'go' )
1216
1217 matplotlib.pyplot.show()
1218
1219
1220
1221**9. Running in MPI mode (multiprocessor configuration)**
1222----------------------------------------------------------
1223
1224* We assume that an MPI implementation is installed on your machine (e.g. OpenMPI).
1225If you want to run python-meep in MPI mode, then you must must import the ``meep_mpi`` module instead of the ``meep`` module :
1226
1227``from meep_mpi import *``
1228
1229Then start up the Python script as follows :
1230
1231``mpirun -n 2 ./myscript.py``
1232
1233The ``-n`` parameter indicates the number of processors requested.
1234
1235* For printing output to the console, use the ``master_printf`` statement. This will generate output on the master node only (regular Python ``print`` statements will run on all nodes).
1236
1237* If you output HDF5 files, make sure your HDF5 library is MPI-enable, otherwise your Python script will stall upon writing HDF5 due to a deadlock.
1238
1239
1240
1241**10. Differences between Python-Meep and Scheme-Meep (libctl)**
1242------------------------------------------------------------------
1243
1244**note**: this section does NOT apply to the UGent Intec Photonics Research Group (apart from the coordinate system, the default behaviour for us is made consistent with Scheme-Meep)
1245
1246The general rule is that Python-Meep has consistent behaviour with the **C++ core of Meep**.
1247The default version of Python-Meep (compiled from the LATEST_RELEASE branch) has 3 differences compared with the Scheme version of Meep :
1248 * in Python-meep, the center of the coordinate system is in the upper left corner (in Scheme-Meep v1.1.1, the center of the coordinate system is in the middle of your computational volume).
1249 * in Python-meep, eps-averaging is disabled by default (see section 3.2 for details on how to enable eps-averaging)
1250 * in Python-meep, calculation is done with complex fields by default (in Scheme-Meep v1.1.1, real fields are used by default). You can call function use_real_fields() on your fields-object to enable calculation with real fields only.
1251
1252On starting your script, Python-Meep will warn you about these differences. You can suppress these warning by setting the global variables ``DISABLE_WARNING_COORDINATESYSTEM``, ``DISABLE_WARNING_EPS_AVERAGING`` and ``DISABLE_WARNING_REAL_FIELDS`` to ``True``. You can add site-specific customisations to the file ``meep-site-init.py`` : in this script, you can for example suppress the warning, or enable EPS-averaging by default.
1253
1254Add the following code to ``meep-site-init.py`` if you want *to calculate with real fields only by default* :
1255
1256::
1257
1258 #by default enable calculation with real fields only (consistent with Scheme-meep)
1259 def fields(structure, m = 0, store_pol_energy=0):
1260 f = fields_orig(structure, m, store_pol_energy)
1261 f.use_real_fields()
1262 return f
1263
1264 #add a new construct 'fields_complex' that you can use to force calculation with complex fields
1265 def fields_complex(structure, m = 0, store_pol_energy=0):
1266 master_printf("Calculation with complex fields enalbed.\n")
1267 return fields_orig(structure, m, store_pol_energy)
1268
1269 global DISABLE_WARNING_REAL_FIELDS
1270 DISABLE_WARNING_REAL_FIELDS = True
1271
1272
1273Add the following code to ``meep-site-init.py`` if you want *to enable EPS-averaging by default* :
1274
1275::
1276
1277 use_averaging(True)
1278
1279 global DISABLE_WARNING_EPS_AVERAGING
1280 DISABLE_WARNING_EPS_AVERAGING = True
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
01294
=== added directory 'doc/html/_sources/.svn/tmp'
=== added directory 'doc/html/_sources/.svn/tmp/prop-base'
=== added directory 'doc/html/_sources/.svn/tmp/props'
=== added directory 'doc/html/_sources/.svn/tmp/text-base'
=== added file 'doc/html/_sources/python_meep_documentation.txt'
--- doc/html/_sources/python_meep_documentation.txt 1970-01-01 00:00:00 +0000
+++ doc/html/_sources/python_meep_documentation.txt 2009-12-01 14:23:10 +0000
@@ -0,0 +1,1299 @@
1PYTHON-MEEP BINDING DOCUMENTATION
2====================================
3
4Primary author of this documentation : EL : Emmanuel.Lambert@intec.ugent.be
5
6Document history :
7
8::
9
10 * EL-19/20/21-08-2009 : document creation
11 * EL-24-08-2009 : small improvements & clarifications.
12 * EL-25/26-08-2009 : sections 7 & 8 were added.
13 * EL-03-04/09/2009 :
14 -class "structure_eps_pml" (removed again in v0.8).
15 -port to Meep 1.1.1 (class 'volume' was renamed to 'grid_volume' and class 'geometric_volume' to 'volume'
16 -minor changes in the bent waveguide sample, to make it more consistent with the Scheme version
17 * EL-07-08/09/2009 : sections 3.2, 8.2, 8.3 : defining a material function with inline C/C++
18 * EL-10/09/2009 : additions for MPI mode (multiprocessor)
19 * EL-21/10/2009 : amplitude factor callback function
20 * EL-22/10/2009 : keyword arguments for runUntilFieldsDecayed
21 * EL-01/12/2009 : alignment with version 0.8 - III
22 * EL-01/12/2009 : release 1.0 / added info about environment variables for inline C/C++
23
24
25
26**1. The general structure of a python-meep program**
27-----------------------------------------------------
28
29In general terms, a python-meep program can be structured as follows :
30
31 * import the python-meep binding :
32 ``from meep import *``
33 This will load the library ``_meep.so`` and Python-files ``meep.py`` and ``python_meep.py`` from path ``/usr/local/lib/python2.6/dist-packages/``
34
35 If you are running in MPI mode (multiprocessor, see section 9), then you have to import module ``meep_mpi`` instead :
36 ``from meep_mpi import *``
37
38 * define a computational grid volume
39 See section 2 below which explains usage of the ``grid_volume`` class.
40
41 * define the waveguide structure (describing the geometry, PML and materials)
42 See section 3 below which explains usage of the ``structure`` class.
43
44 * create an object which will hold the calculated fields
45 See section 4 below which explains usage of the ``field`` class.
46
47 * define the sources
48 See section 5 below which explains usage of the ``add_point_source`` and ``add_volume_source`` functions.
49
50 * run the simulation (iterate over the time-steps)
51 See section 6 below.
52
53Section 7 gives details about defining and retrieving fluxes.
54
55Section 9 gives some complete examples.
56
57Section 10 outlines some differences between Scheme-Meep and Python-Meep.
58
59
60**2. Defining the computational grid volume**
61---------------------------------------------
62
63The following set of 'factory functions' is provided, aimed at creating a ``grid_volume`` object. The first arguments define the size of the computational volume, the last argument is the computational grid resolution (in pixels per distance unit).
64 * ``volcyl(rsize, zsize, resolution)``
65 Defines a cyclical computational grid volume.
66 * ``volone(zsize, resolution)`` *alternatively called* ``vol1d(zsize, resolution)``
67 Defines a 1-dimensional computational grid volume along the Z-axis.
68 * ``voltwo(xsize, ysize, resolution)`` *alternatively called* ``vol2d(xsize, ysize, a)``
69 Defines a 2-dimensional computational grid volumes along the X- and Y-axes
70 * ``vol3d(xsize, ysize, zsize, resolution)``
71 Defines a 3-dimensional computational grid volume.
72
73 e.g.: ``v = volone(6, 10)`` defines a 1-dimensional computational volume of lenght 6, with 10 pixels per distance unit.
74
75
76**3. Defining the waveguide structure**
77---------------------------------------
78
79The waveguide structure is defined using the class ``structure``, of which the constructor has the following arguments :
80
81 * *required* : the computational grid volume (a reference to an object of type ``grid_volume``, see section 2 above)
82
83 * *required* : a function defining the dielectric properties of the materials in the computational grid volume (thus describing the actual waveguide structure). For all-air, the predefined function 'one' can be used (epsilon = constant value 1). See note 3.1 below for more information about defining your own custom material function.
84
85 * *optional* : a boundary region: this is a reference to an object of type ``boundary_region``. There are a number of predefined functions that can be used to create such an object :
86 - ``no_pml()`` describing a conditionless boundary region (no PML)
87 - ``pml(thickness)`` : decribing a perfectly matching layer (PML) of a certain thickness (double value) on the boundaries in all directions.
88 - ``pml(thickness, direction)`` : decribing a perfectly matching layer (PML) of a certain thickness (double value) in a certain direction (``X, Y, Z, R or P``).
89 - ``pml(thickness, direction, boundary_side)`` : describing a PML of a certain thickness (double value), in a certain direction (``X, Y, Z, R or P``) and on the ``High`` or ``Low`` side. E.g. if boundary_side is ``Low`` and direction is ``X``, then a PML layer is added to the −x boundary. The default puts PML layers on both sides of the direction.
90
91 * *optional* : a function defining a symmetry to exploit, in order to speed up the FDTD calculation (reference to an object of type ``symmetry``). The following predefined functions can be used to create a ``symmetry`` object:
92 - ``identity`` : no symmetry
93 - ``rotate4(direction, grid_volume)`` : defines a 90° rotational symmetry with 'direction' the axis of rotation.
94 - ``rotate2(direction, grid_volume)`` : defines a 180° rotational symmetry with 'direction' the axis of rotation.
95 - ``mirror(direction, grid_volume)`` : defines a mirror symmetry plane with 'direction' normal to the mirror plane.
96 - ``r_to_minus_r_symmetry`` : defines a mirror symmetry in polar coordinates
97
98 * optional: the number of chunks in which to split up the calculated geometry. If you leave this empty, it is auto-configured. Otherwise, you would set this to a factor which is a multiple of the number of processors in your MPI run (for multiprocessor configuration).
99
100 e.g. : if ``v`` is a variable pointing to the computational grid volume, then :
101 ``s = structure(v, one)`` defines a structure with all air (eps=1),
102 which is equivalent to:
103 ``s = structure(v, one, no_pml(), identity(), 1)``
104
105 Another example : ``s = structure(v, EPS, pml(0.1,Y) )`` with EPS a custom material function, which is explained in the note below.
106
107
1083.1. Defining a material function
109________________________________________
110
111In order to describe the geometry of the waveguide, we have to provide a 'material function' returning the dielectric variable epsilon as a function of the position (identified by a vector). In python-meep, we can do this by defining a class that inherits from class ``Callback``. Through this inheritance, the core meep library (written in C++) will be able to call back to the Python function which describes the material properties.
112It is also possible (and faster) to write your material function in inline C/C++ (see 3.3)
113
114E.g. :
115
116::
117
118 class epsilon(Callback): #inherit from Callback for integration with the meep core library
119 def __init__(self):
120 Callback.__init__(self)
121 def double_vec(self,vec): #override of function in the Callback class to set the eps function
122 self.set_double(self.eps(vec))
123 return
124 def eps(self,vec): #return the epsilon value for a certain point (indicated by the vector v)
125 v = vec
126 r = v.x()*v.x() + v.y()*v.y()
127 dr = sqrt(r)
128 while dr>1:
129 dr-=1
130 if dr > 0.7001:
131 return 12.0
132 return 1.0
133
134Please note the **brackets** when referring to the x- and y-components of the vector ``vec``. These are **crucial** : no error message will be thrown if you refer to it as vec.x or vec.y, but the value will always be zero.
135So, one should write : ``vec.x()`` and ``vec.y()``.
136
137The meep-python library has a 'global' variable EPS, which is used as a reference for communication between the Meep core library and the Python code. We assign our epsilon-function as follows to the global EPS variable :
138
139::
140
141 set_EPS_Callback(epsilon().__disown__())
142 s = structure(v, EPS, no_pml(), identity())
143
144
145The call to function ``__disown__()`` is for memory management purposes and is *absolutely required*. An improvement of the python-meep binding could consist of making this call transparant for the end user. But for now, the user must manually provide it.
146
147***Important remark*** : at the end of our program, we should call : ``del_EPS_Callback()`` in order to clean up the global variable.
148
149For better performance, you can define your EPS material function with inline C/C++ : we refer to section 3.3 for details about this.
150
1513.2 Eps-averaging
152_________________
153
154EPS-averaging (anisotrpic averaging) is disabled by default, making this behaviour consistent with the behaviour of the Meep C++ core.
155
156You can enable EPS-averaging using the function ``use_averaging`` :
157
158::
159
160 #enable EPS-averaging
161 use_averaging(True)
162 ...
163 #disable EPS-averaging
164 use_averaging(False)
165 ...
166
167
168Enabling EPS-averaging results in slower performance, but more accurate results.
169
170
1713.3. Defining a material function with inline C/C++
172_________________________________________________________
173
174The approach described in 3.1 lets the Meep core library call back to Python for every query of the epsilon-function. This creates a lot of overhead.
175An approach which has a lot better performance is to define this epsilon-function with an inline C-function or C++ class.
176
177* If our epsilon-function needs *no other parameters than the position vector (X, Y, Z)*, then we can suffice with an inline C-function (the geometry dependencies are then typically hardcoded).
178
179* If our epsilon-function needs to base it's calculation on *a more complex set of parameters (e.g. parameters depending on the geometry)*, then we have to write a C++ class.
180
181For example, in the bent-waveguide example (section 8.3), we can define a generic C++ class which can return the epsilon-value for both the "bend" and "no bend" case, with variable size parameters.
182We can also take a simpler approach (section 8.2) and write a function in which the geometry size parameters are hardcoded : we then need 2 inline C-functions : one for the "bend" case and one for the "no bend" case.
183
184Make sure the following environment variables are defined :
185 * MEEP_INCLUDE : should point to the path containing meep.hpp (and a subdirectory 'meep' with vec.hpp and mympi.hpp), e.g.: ``/usr/include``
186 * MEEP_LIB : should point to the path containing libmeep.so, e.g. : ``/usr/lib``
187 * PYTHONMEEP_INCLUDE : should point to the path containing custom.hpp, e.g. : ``/usr/local/lib/python2.6/dist-packages``
188
189
1903.3.1 Inline C-function
191.......................
192
193First we create a header file, e.g. "eps_function.hpp" which contains our EPS-function.
194Not that the geometry dependencies are hardcoded (``upperLimitHorizontalWg = 4`` and ``lowerLimitHorizontalWg = 5``).
195
196::
197
198
199 namespace meep
200 {
201 static double myEps(const vec &v) {
202 double xCo = v.x();
203 double yCo = v.y();
204 double upperLimitHorizontalWg = 4;
205 double lowerLimitHorizontalWg = 5;
206 if ((yCo < upperLimitHorizontalWg) || (yCo > lowerLimitHorizontalWg)){
207 return 1.0;
208 }
209 else return 12.0;
210 }
211 }
212
213
214Then, in the Python program, we prepare and set the callback function as shown below.
215``prepareCallbackCfunction`` returns a pointer to the C-function, which we deliver to the Meep core using ``set_EPS_CallbackInlineFunction``.
216
217::
218
219 def initEPS(isWgBent):
220 funPtr = prepareCallbackCfunction("myEps","eps_function.hpp") #name of your function / name of header file
221 set_EPS_CallbackInlineFunction(funPtr)
222 print "EPS function successfully set."
223 return funPtr
224
225We refer to section 8.2 below for a full example.
226
227
2283.3.2 Inline C++-class
229......................
230
231A more complex approach is to have a C++ object that can accept more parameters when it is constructed.
232For example this is the case if want to change the parameters of the geometry from inside Python without touching the C++ code.
233
234We create a header file "eps_class.hpp" which contains the definition of the class (the class must inherit from ``Callback``).
235In the example below, the parameters ``upperLimitHorizontalWg`` and ``widthWg`` will be communicated from Python upon construction of the object.
236If these parameters then change (depending on the geometry), the C++ object will follow automatically.
237
238
239::
240
241 using namespace meep;
242
243 namespace meep
244 {
245
246 class myEpsCallBack : virtual public Callback {
247
248 public:
249 myEpsCallBack() : Callback() { };
250 ~myEpsCallBack() { cout << "Callback object destructed." << endl; };
251
252 myEpsCallBack(double upperLimitHorizontalWg, double widthWg) : Callback() {
253 _upperLimitHorizontalWg = upperLimitHorizontalWg;
254 _widthWg = widthWg;
255 };
256
257 double double_vec(const vec &v) { //return the EPS-value, depending on the position vector
258 double eps = myEps(v, _upperLimitHorizontalWg, _widthWg);
259 return eps;
260 };
261
262 complex<double> complex_vec(const vec &x) { return 0; }; //no need to implement
263 complex<double> complex_time(const double &t) { return 0; }; //no need to implement
264
265
266 private:
267 double _upperLimitHorizontalWg;
268 double _widthWg;
269
270 double myEps(const vec &v, double upperLimitHorizontalWg, double widthWg) {
271 double xCo = v.x();
272 double yCo = v.y();
273 if ((yCo < upperLimitHorizontalWg) || (yCo > upperLimitHorizontalWg+widthWg)){
274 return 1.0;
275 }
276 }
277 return 12.0;
278 }
279
280 };
281
282 }
283
284
285The syntax in Python is a little bit more complex in this case.
286
287We will need to import the module ``scipy.weave`` :
288
289``from scipy.weave import *``
290
291(this is not required for the previous case of a simple inline function)
292
293First we create a list with the names of the parameters that we want to pass to the C++ class. These variables must be declared in the scope where the ``inline`` function call happens (see below).
294
295``c_params = ['upperLimitHorizontalWg','widthWg']``
296
297Then, we prepare the code snippet, using the function ``prepareCallbackCObjectCode`` and passing the class name and parameter names list.
298
299``c_code = prepareCallbackCObjectCode("myEpsCallBack", c_params)``
300
301Finally, we call the ``inline`` function, passing :
302 * the code snippet
303 * the list of parameter names
304 * the inline libraries, include directories and headers (helper functions are provided for this, see below). The call to ``getInlineHeaders`` should receive the name of the header file (with the definition of the C++ class) as an argument.
305
306``funPtr = inline(c_code,c_params, libraries=getInlineLibraries(), include_dirs = getInlineInclude(), headers = getInlineHeaders("eps_class.hpp") )``
307
308::
309
310
311 def initEPS():
312 #the set of parameters that we want to pass to the Callback object upon construction
313 #all these variables must be declared in the scope where the "inline" function call happens
314 c_params = ['upperLimitHorizontalWg','widthWg']
315 #the C-code snippet for constructing the Callback object
316 c_code = prepareCallbackCObjectCode("myEpsCallBack", c_params)
317 #do the actual inline C-call and fetch the pointer to the Callback object
318 funPtr = inline(c_code,c_params, libraries=getInlineLibraries(), include_dirs = getInlineInclude(), headers = getInlineHeaders("eps_class.hpp") )
319 #set the pointer to the callback object in the Python-meep core
320 set_EPS_CallbackInlineObject(funPtr)
321 print "EPS function successfully set."
322 return
323
324
325We refer to section 8.3 below for a full example.
326
327
328
329**4. Defining the initial field**
330---------------------------------
331
332This is optional.
333
334We create an object of type ``fields``, which will contain the calculated field.
335
336We must first create a Python class that inherits from class ``Callback`` and that will define the function for initialization of the field. Inheritance from class ``Callback`` is required, because the core meep library (written in C++) will have to call back to the Python function. For example, let's call our initialization class ``fi``.
337
338::
339
340 class fi(Callback): #inherit from Callback for integration with the meep core library
341 def __init__(self):
342 Callback.__init__(self)
343 def complex_vec(self,v): #override of function in the Callback class to set the field initialization function
344 #return the field value for a certain point (indicated by the vector v)
345 return complex(1.0,0)
346
347The meep-python library has a 'global' variable INIF, that is used to bind the meep core library to our Python field initialization class. To set INIF, we have to use the following statement :
348
349 ``set_INIF_Callback(fi().__disown__()) #link the INIF variable to the fi class``
350
351We refer to section 3-note1 for more information about the function ``__disown__()``.
352
353E.g.: If ``s`` is a variable pointing to the structure and ``comp`` denotes the component which we are initializing, then the complete field initialization code looks as follows :
354
355::
356
357 f = fields(s)
358 comp = Hy
359 f.initialize_field(comp, INIF)
360
361
362***Important remark*** : at the end of our program, we should then call : ``del_INIF_Callback()`` in order to clean up the global variable.
363
364The call to ``initialize_field`` is not mandatory. If the initial conditions are zeros for all components, then we can rely on the automatic initialization at creation of the object.
365
366We can additionally define **Bloch-periodic boundary conditions** over the field. This is done with the ``use_bloch`` function of the field class, e.g. :
367
368 ``f.use_bloch(vec(0.0))``
369
370*to be further elaborated - what is the exact meaning of the vector argument? (not well understood at this time)*
371
372
373
374**5. Defining the sources**
375---------------------------
376
377The definition of the current sources can be done through 2 functions of the ``fields`` class :
378 * ``add_point_source(component, src_time, vec, complex)``
379 * ``add_volume_source(component, src_time, volume, complex)``
380
381
382Each require as arguments an electromagnetic component (e.g. ``Ex, Ey, ...`` and ``Hx, Hy, ...``) and an object of type ``src_time``, which specifies the time dependence of the source (see below).
383
384For a point source, we must specify the center point of the current source using a vector (object of type ``vec``).
385
386For a volume source, we must specify an object of type ``volume`` (*to be elablorated*).
387
388The last argument is an overall complex amplitude number, multiplying the current source (default 1.0).
389
390The following variants are available :
391 * ``add_point_source(component, double, double, double, double, vec centerpoint, complex amplitude, int is_continuous)``
392 * This is a shortcut function so that no ``src_time`` object must be created. *This function is preferably used for point sources.*
393 * The four real arguments define the central frequency, spectral width, peaktime and cutoff.
394
395 * ``add_volume_source(component, src_time, volume)``
396
397 * ``add_volume_source(component, src_time, volume, AMPL)``
398 * AMPL is a built-in reference to a callback function. Such a callback function returns a factor to multiply the source amplitude with (complex value). It receives 1 parameter, i.e. a vector indicating a position RELATIVE to the CENTER of the source. See the example below.
399
400
401Three classes, inheriting from ``src_time``, are predefined and can be used off the shelf :
402 * ``gaussian_src_time`` for a Gaussian-pulse source. The constructor demands 2 arguments of type double :
403 * the center frequency ω, in units of 2πc
404 * the frequency width w used in the Gaussian
405 * ``continuous_src_time`` for a continuous-wave source proportional to exp(−iωt). The constructor demands 4 arguments :
406 * the frequency ω, in units 2πc/distance (complex number)
407 * the temporal width of smoothing (default 0)
408 * the start time (default 0)
409 * the end time (default infinity = never turn off)
410 * ``custom_src_time`` for a user-specified source function f(t) with start/end times. The constructor demands 4 arguments :
411 * The function f(t) specifying the time-dependence of the source
412 * *...(2nd argument unclear, to be further elaborated)...*
413 * the start time of the source (default -infinity)
414 * the end time of the source (default +infinity)
415
416For example, in order to define a continuous line source of length 1, from point (6,3) to point (6,4) in 2-dimensional geometry :
417
418::
419
420 #define a continuous source
421 srcFreq = 0.125
422 srcWidth = 20
423 src = continuous_src_time(srcFreq, srcWidth, 0, infinity)
424 srcComp = Ez
425 #make it a line source of size 1 starting on position(6,3)
426 srcGeo = volume(vec(6,3),vec(6,4))
427 f.add_volume_source(srcComp, src, srcGeo)
428
429
430Here is an example of the implementation of a callback function for the amplitude factor :
431
432::
433
434 class amplitudeFactor(Callback):
435 def __init__(self):
436 Callback.__init__(self)
437 master_printf("Callback function for amplitude factor activated.\n")
438
439 def complex_vec(self,vec):
440 #BEWARE, these are coordinates RELATIVE to the source center !!!!
441 x = vec.x()
442 y = vec.y()
443 master_printf("Fetching amplitude factor for x=%f - y=%f\n" %(x,y) )
444 result = complex(1.0,0)
445 return result
446
447 ...
448 #define a continuous source
449 srcFreq = 0.125
450 srcWidth = 20
451 src = continuous_src_time(srcFreq, srcWidth, 0, infinity)
452 srcComp = Ez
453 #make it a line source of size 1 starting on position(6,3)
454 srcGeo = volume(vec(6,3),vec(6,4))
455 #create callback object for amplitude factor
456 af = amplitudeFactor()
457 set_AMPL_Callback(af.__disown__())
458 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, AMPL)
459
460
461**6. Running the simulation, retrieving field values and exporting HDF5 files**
462-------------------------------------------------------------------------------
463
464We can now time-step and retrieve various field values along the way.
465The actual time step value can be retrieved or set through the variable ``f.dt``.
466
467The default time step in Meep is : ``Courant factor / resolution`` (in FDTD, the Courant factor relates the time step size to the spatial discretization: cΔt = SΔx. Default for S is 0.5). If no further parametrization is done, then this default value is used.
468
469To trigger a step in time, you call the function ``f.step()``.
470
471To step until the source has fully decayed :
472
473::
474
475 while (f.time() < f.last_source_time()):
476 f.step()
477
478The function ``runUntilFieldsDecayed`` mimicks the behaviour of 'stop-when-fields-decayed' in Meep-Scheme.
479This will run time steps until the source has decayed to 0.001 of the peak amplitude. After that, by default an additional 50 time steps will be run.
480The function has 7 arguments, of which 4 are mandatory and 3 are optional keywords arguments :
481* 4 regular arguments : reference to the field, reference to the computational grid volume, the source component, the monitor point.
482* keyword argument ``pHDF5OutputFile`` : reference to a HDF5 file (constructed with the function ``prepareHDF5File``); default : None (no ouput to files)
483* keyword argument ``pH5OutputIntervalSteps`` : step interval for output to HDF5 (default : 50)
484* keyword argument ``pDecayedStopAfterSteps`` : the number of steps to continue after the source has decayed to 0.001 of the peak amplitude at the probing point (default: 50)
485
486We further refer to section 8 below where this function is applied in an example.
487
488A rich functionality is available for retrieving field information. Some examples :
489
490 * ``f.energy_in_box(v.surroundings())``
491 * ``f.electric_energy_in_box(v.surroundings())``
492 * ``f.magnetic_energy_in_box(v.surroundings())``
493 * ``f.thermo_energy_in_box(v.surroundings())``
494 * ``f.total_energy()``
495 * ``f.field_energy_in_box(v.surroundings())``
496 * ``f.field_energy_in_box(component, v.surroundings())`` where the first argument is the electromagnetic component (``Ex, Ey, Ez, Er, Ep, Hx, Hy, Hz, Hr, Hp, Dx, Dy, Dz, Dp, Dr, Bx, By, Bz, Bp, Br, Dielectric`` or ``Permeability``)
497 * ``f.flux_in_box(X, v.surroundings())`` where the first argument is the direction (``X, Y, Z, R`` or ``P``)
498
499We can probe the field at certain points by defining a *monitor point* as follows :
500
501::
502
503 m = monitor_point()
504 p = vec(2.10) #vector identifying the point that we want to probe
505 f.get_point(m, p)
506 m.get_component(Hx)
507
508We can export the dielectric function and e.g. the Ex component of the field to HDF5 files as follows :
509
510::
511
512 #make sure you start your Python session with 'sudo' or write rights to the current path
513 feps = prepareHDF5File("eps.h5")
514 f.output_hdf5(Dielectric, v.surroundings(), feps) #export the Dielectric structure so that we can visually verify it
515 fex = prepareHDF5File("ex.h5")
516 while (f.time() < f.last_source_time()):
517 f.step()
518 f.output_hdf5(Ex, v.surroundings(), fex, 1) #export the Ex component, appending to the file "ex.h5"
519
520
521
522**7. Defining and retrieving fluxes**
523--------------------------------------
524
525First we define a flux plane.
526This is done through the creation of an object of type ``volume`` (specifying 2 vectors as arguments).
527
528Then we apply this flux plane to the field, specifying 4 parameters :
529 * the reference to the ``volume`` object
530 * the minimum frequency (in the example below, this is ``srcFreqCenter-(srcPulseWidth/2.0)``)
531 * the maximum frequency (in the example below this is ``srcFreqCenter+(srcPulseWidth/2.0)`` )
532 * the number of discrete frequencies that we want to monitor in the flux (in the example below, this is 100).
533
534After running the simulation, we can retrieve the flux values through the function ``getFluxData()`` : this returns a 2-dimensional array with the frequencies and actual flux values.
535
536E.g., if ``f`` is the field, then we proceed as follows :
537
538::
539
540 #define the flux plane and flux parameters
541 fluxplane = volume(vec(1,2),vec(1,3))
542 flux = f.add_dft_flux_plane(fluxplane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
543
544 #run the calculation
545 while (f.time() < f.last_source_time()):
546 f.step()
547
548 #retrieve the flux data
549 fluxdata = getFluxData(flux)
550 frequencies = fluxdata[0]
551 fluxvalues = fluxdata[1]
552
553
554
555**8. The "90 degree bent waveguide example in Python**
556------------------------------------------------------
557
558We have ported the "90 degree bent waveguide" example from the Meep-Scheme tutorial to Python.
559
560The original example can be found on the following URL : http://ab-initio.mit.edu/wiki/index.php/Meep_Tutorial
561(section 'A 90° bend').
562
563You can find the source code below and also in the ``/samples/bent_waveguide`` directory of the Python-Meep distribution.
564
565Sections 8.2 and 8.3 contain the same example but with the EPS-callback function as inline C-function and inline C++-class.
566
567The following animated gifs can be produced from the HDF5-files (see the script included in directory 'samples') :
568
569.. image:: images/bentwgNB.gif
570
571.. image:: images/bentwgB.gif
572
573
574And here is the graph of the transmission, reflection and loss fluxes, showing the same results as the example in Scheme:
575
576.. image:: images/fluxes.png
577 :height: 315
578 :width: 443
579
580
5818.1 With a Python class as EPS-function
582________________________________________
583
584
585A bottleneck in this version is the epsilon-function, which is written in Python.
586This means that the Meep core library must do a callback to the Python function, which creates a lot of overhead.
587An approach which has a much better performance is to write this EPS-function in C : the Meep core library can then directly call back to a C-function.
588These approaches are described in 8.2 and 8.3.
589
590::
591
592 from meep import *
593 from math import *
594 from python_meep import *
595 import numpy
596 import matplotlib.pyplot
597 import sys
598
599 res = 10.0
600 gridSizeX = 16.0
601 gridSizeY = 32.0
602 padSize = 4.0
603 wgLengthX = gridSizeX - padSize
604 wgLengthY = gridSizeY - padSize
605 wgWidth = 1.0 #width of the waveguide
606 wgHorYCen = padSize + wgWidth/2.0 #horizontal waveguide center Y-pos
607 wgVerXCen = wgLengthX - wgWidth/2.0 #vertical waveguide center X-pos (in case there is a bend)
608 srcFreqCenter = 0.15 #gaussian source center frequency
609 srcPulseWidth = 0.1 #gaussian source pulse width
610 srcComp = Ez #gaussian source component
611
612 #this function plots the waveguide material as a function of a vector(X,Y)
613 class epsilon(Callback):
614 def __init__(self, pIsWgBent):
615 Callback.__init__(self)
616 self.isWgBent = pIsWgBent
617 def double_vec(self,vec):
618 if (self.isWgBent): #there is a bend
619 if ((vec.x()<wgLengthX) and (vec.y() >= padSize) and (vec.y() <= padSize+wgWidth)):
620 return 12.0
621 elif ((vec.x()>=wgLengthX-wgWidth) and (vec.x()<=wgLengthX) and vec.y()>= padSize ):
622 return 12.0
623 else:
624 return 1.0
625 else: #there is no bend
626 if ((vec.y() >= padSize) and (vec.y() <= padSize+wgWidth)):
627 return 12.0
628 else:
629 return 1.0
630
631 def createField(pCompVol, pWgLengthX, pWgWidth, pIsWgBent, pSrcFreqCenter, pSrcPulseWidth, pSrcComp):
632 #we create a structure with PML of thickness = 1.0 on all boundaries,
633 #in all directions,
634 #using the material function EPS
635 material = epsilon(pIsWgBent)
636 set_EPS_Callback(material.__disown__())
637 s = structure(pCompVol, EPS, pml(1.0) )
638 f = fields(s)
639 #define a gaussian line source of length 'wgWidth' at X=wgLength/2, Y=padSize
640 srcGaussian = gaussian_src_time(pSrcFreqCenter, pSrcPulseWidth )
641 srcGeo = volume(vec(1.0,padSize),vec(1.0,padSize+pWgWidth))
642 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, 1)
643 print "Field created..."
644 return f
645
646
647 #FIRST WE WORK OUT THE CASE WITH NO BEND
648 #----------------------------------------------------------------
649 print "*1* Starting the case with no bend..."
650 #create the computational grid
651 noBendVol = voltwo(gridSizeX,gridSizeY,res)
652
653 #create the field
654 wgBent = 0 #no bend
655 noBendField = createField(noBendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
656
657 bendFnEps = "./bentwgNB_Eps.h5"
658 bendFnEz = "./bentwgNB_Ez.h5"
659 #export the dielectric structure (so that we can visually verify the waveguide structure)
660 noBendDielectricFile = prepareHDF5File(bendFnEps)
661 noBendField.output_hdf5(Dielectric, noBendVol.surroundings(), noBendDielectricFile)
662
663 #create the file for the field components
664 noBendFileOutputEz = prepareHDF5File(bendFnEz)
665
666 #define the flux plane for the reflected flux
667 noBendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
668 noBendReflectedFluxPlane = volume(vec(noBendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
669 noBendReflectedFlux = noBendField.add_dft_flux_plane(noBendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
670
671 #define the flux plane for the transmitted flux
672 noBendTransmfluxPlaneXPos = gridSizeX - 1.5; #the X-coordinate of our transmission flux plane
673 noBendTransmFluxPlane = volume(vec(noBendTransmfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendTransmfluxPlaneXPos,wgHorYCen+wgWidth))
674 noBendTransmFlux = noBendField.add_dft_flux_plane(noBendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
675
676 print "Calculating..."
677 noBendProbingpoint = vec(noBendTransmfluxPlaneXPos,wgHorYCen) #the point at the end of the waveguide that we want to probe to check if source has decayed
678 runUntilFieldsDecayed(noBendField, noBendVol, srcComp, noBendProbingpoint, noBendFileOutputEz)
679 print "Done..!"
680
681 #construct 2-dimensional array with the flux plane data
682 #see python_meep.py
683 noBendReflFlux = getFluxData(noBendReflectedFlux)
684 noBendTransmFlux = getFluxData(noBendTransmFlux)
685
686 #save the reflection flux from the "no bend" case as minus flux in the temporary file 'minusflux.h5'
687 noBendReflectedFlux.scale_dfts(-1);
688 f = open("minusflux.h5", 'w') #truncate file if already exists
689 f.close()
690 noBendReflectedFlux.save_hdf5(noBendField, "minusflux")
691
692 del_EPS_Callback()
693
694
695 #AND SECONDLY FOR THE CASE WITH BEND
696 #----------------------------------------------------------------
697 print "*2* Starting the case with bend..."
698 #create the computational grid
699 bendVol = voltwo(gridSizeX,gridSizeY,res)
700
701 #create the field
702 wgBent = 1 #there is a bend
703 bendField = createField(bendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
704
705 #export the dielectric structure (so that we can visually verify the waveguide structure)
706 bendFnEps = "./bentwgB_Eps.h5"
707 bendFnEz = "./bentwgB_Ez.h5"
708 bendDielectricFile = prepareHDF5File(bendFnEps)
709 bendField.output_hdf5(Dielectric, bendVol.surroundings(), bendDielectricFile)
710
711 #create the file for the field components
712 bendFileOutputEz = prepareHDF5File(bendFnEz)
713
714 #define the flux plane for the reflected flux
715 bendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
716 bendReflectedFluxPlane = volume(vec(bendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(bendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
717 bendReflectedFlux = bendField.add_dft_flux_plane(bendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
718
719 #load the minused reflection flux from the "no bend" case as initalization
720 bendReflectedFlux.load_hdf5(bendField, "minusflux")
721
722
723 #define the flux plane for the transmitted flux
724 bendTransmfluxPlaneYPos = padSize + wgLengthY - 1.5; #the Y-coordinate of our transmission flux plane
725 bendTransmFluxPlane = volume(vec(wgVerXCen - wgWidth,bendTransmfluxPlaneYPos),vec(wgVerXCen + wgWidth,bendTransmfluxPlaneYPos))
726 bendTransmFlux = bendField.add_dft_flux_plane(bendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
727
728 print "Calculating..."
729 bendProbingpoint = vec(wgVerXCen,bendTransmfluxPlaneYPos) #the point at the end of the waveguide that we want to probe to check if source has decayed
730 runUntilFieldsDecayed(bendField, bendVol, srcComp, bendProbingpoint, bendFileOutputEz)
731 print "Done..!"
732
733 #construct 2-dimensional array with the flux plane data
734 #see python_meep.py
735 bendReflFlux = getFluxData(bendReflectedFlux)
736 bendTransmFlux = getFluxData(bendTransmFlux)
737
738 del_EPS_Callback()
739
740 #SHOW THE RESULTS IN A PLOT
741 frequencies = bendReflFlux[0] #should be equal to bendTransmFlux.keys() or noBendTransmFlux.keys() or ...
742 Ptrans = [x / y for x,y in zip(bendTransmFlux[1], noBendTransmFlux[1])]
743 Prefl = [ abs(x / y) for x,y in zip(bendReflFlux[1], noBendTransmFlux[1]) ]
744 Ploss = [ 1-x-y for x,y in zip(Ptrans, Prefl)]
745
746 matplotlib.pyplot.plot(frequencies, Ptrans, 'bo')
747 matplotlib.pyplot.plot(frequencies, Prefl, 'ro')
748 matplotlib.pyplot.plot(frequencies, Ploss, 'go' )
749
750 matplotlib.pyplot.show()
751
752
7538.2 With an inline C-function as EPS-function
754______________________________________________
755
756The header file "eps_function.hpp" :
757
758::
759
760 using namespace meep;
761
762 namespace meep
763 {
764 static double myEps(const vec &v, bool isWgBent) {
765 double xCo = v.x();
766 double yCo = v.y();
767 double upperLimitHorizontalWg = 4;
768 double wgLengthX = 12;
769 double leftLimitVerticalWg = 11;
770 double lowerLimitHorizontalWg = 5;
771 if (isWgBent){ //there is a bend
772 if ((yCo < upperLimitHorizontalWg) || (xCo>wgLengthX)){
773 return 1.0;
774 }
775 else {
776 if ((xCo < leftLimitVerticalWg) && (yCo > lowerLimitHorizontalWg)) {
777 return 1.0;
778 }
779 else {
780 return 12.0;
781 }
782 }
783 }
784 else { //there is no bend
785 if ((yCo < upperLimitHorizontalWg) || (yCo > lowerLimitHorizontalWg)){
786 return 1.0;
787 }
788 }
789 return 12.0;
790 }
791
792 static double myEpsBentWg(const vec &v) {
793 return myEps(v, true);
794 }
795
796 static double myEpsStraightWg(const vec &v) {
797 return myEps(v, false);
798 }
799 }
800
801
802
803And the actual Python program :
804
805
806::
807
808
809 from meep import *
810
811 from math import *
812 import numpy
813 import matplotlib.pyplot
814 import sys
815
816 res = 10.0
817 gridSizeX = 16.0
818 gridSizeY = 32.0
819 padSize = 4.0
820 wgLengthX = gridSizeX - padSize
821 wgLengthY = gridSizeY - padSize
822 wgWidth = 1.0 #width of the waveguide
823 upperLimitHorizontalWg = padSize
824 lowerLimitHorizontalWg = padSize+wgWidth
825 leftLimitVerticalWg = wgLengthX-wgWidth
826 wgHorYCen = padSize + wgWidth/2.0 #horizontal waveguide center Y-pos
827 wgVerXCen = wgLengthX - wgWidth/2.0 #vertical waveguide center X-pos (in case there is a bend)
828 srcFreqCenter = 0.15 #gaussian source center frequency
829 srcPulseWidth = 0.1 #gaussian source pulse width
830 srcComp = Ez #gaussian source component
831
832 def initEPS(isWgBent):
833 if (isWgBent):
834 funPtr = prepareCallbackCfunction("myEpsBentWg","eps_function.hpp")
835 else:
836 funPtr = prepareCallbackCfunction("myEpsStraightWg","eps_function.hpp")
837 set_EPS_CallbackInlineFunction(funPtr)
838 print "EPS function successfully set."
839 return funPtr
840
841 def createField(pCompVol, pWgLengthX, pWgWidth, pIsWgBent, pSrcFreqCenter, pSrcPulseWidth, pSrcComp):
842 #we create a structure with PML of thickness = 1.0 on all boundaries,
843 #in all directions,
844 #using the material function EPS
845 s = structure(pCompVol, EPS, pml(1.0) )
846 f = fields(s)
847 #define a gaussian line source of length 'wgWidth' at X=wgLength/2, Y=padSize
848 srcGaussian = gaussian_src_time(pSrcFreqCenter, pSrcPulseWidth )
849 srcGeo = volume(vec(1.0,padSize),vec(1.0,padSize+pWgWidth))
850 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, 1)
851 print "Field created..."
852 return f
853
854
855 master_printf("BENT WAVEGUIDE SAMPLE WITH INLINE C-FUNCTION FOR EPS\n")
856
857 master_printf("Running on %d processor(s)...\n",count_processors())
858
859 #FIRST WE WORK OUT THE CASE WITH NO BEND
860 #----------------------------------------------------------------
861 master_printf("*1* Starting the case with no bend...")
862
863 #set EPS material function
864 initEPS(0)
865
866 #create the computational grid
867 noBendVol = voltwo(gridSizeX,gridSizeY,res)
868
869 #create the field
870 wgBent = 0 #no bend
871 noBendField = createField(noBendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
872
873 bendFnEps = "./bentwgNB_Eps.h5"
874 bendFnEz = "./bentwgNB_Ez.h5"
875 #export the dielectric structure (so that we can visually verify the waveguide structure)
876 noBendDielectricFile = prepareHDF5File(bendFnEps)
877 noBendField.output_hdf5(Dielectric, noBendVol.surroundings(), noBendDielectricFile)
878
879 #create the file for the field components
880 noBendFileOutputEz = prepareHDF5File(bendFnEz)
881
882 #define the flux plane for the reflected flux
883 noBendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
884 noBendReflectedFluxPlane = volume(vec(noBendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
885 noBendReflectedFlux = noBendField.add_dft_flux_plane(noBendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
886
887 #define the flux plane for the transmitted flux
888 noBendTransmfluxPlaneXPos = gridSizeX - 1.5; #the X-coordinate of our transmission flux plane
889 noBendTransmFluxPlane = volume(vec(noBendTransmfluxPlaneXPos,wgHorYCen-wgWidth),vec(noBendTransmfluxPlaneXPos,wgHorYCen+wgWidth))
890 noBendTransmFlux = noBendField.add_dft_flux_plane(noBendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
891
892 master_printf("Calculating...")
893 noBendProbingpoint = vec(noBendTransmfluxPlaneXPos,wgHorYCen) #the point at the end of the waveguide that we want to probe to check if source has decayed
894 runUntilFieldsDecayed(noBendField, noBendVol, srcComp, noBendProbingpoint, noBendFileOutputEz)
895 master_printf("Done..!")
896
897 #construct 2-dimensional array with the flux plane data
898 #see python_meep.py
899 noBendReflFlux = getFluxData(noBendReflectedFlux)
900 noBendTransmFlux = getFluxData(noBendTransmFlux)
901
902 #save the reflection flux from the "no bend" case as minus flux in the temporary file 'minusflux.h5'
903 noBendReflectedFlux.scale_dfts(-1);
904 f = open("minusflux.h5", 'w') #truncate file if already exists
905 f.close()
906 noBendReflectedFlux.save_hdf5(noBendField, "minusflux")
907
908 del_EPS_Callback() #destruct the inline-created object
909
910
911 #AND SECONDLY FOR THE CASE WITH BEND
912 #----------------------------------------------------------------
913 master_printf("*2* Starting the case with bend...")
914
915 #set EPS material function
916 initEPS(1)
917
918 #create the computational grid
919 bendVol = voltwo(gridSizeX,gridSizeY,res)
920
921 #create the field
922 wgBent = 1 #there is a bend
923 bendField = createField(bendVol, wgLengthX, wgWidth, wgBent, srcFreqCenter, srcPulseWidth, srcComp)
924
925 #export the dielectric structure (so that we can visually verify the waveguide structure)
926 bendFnEps = "./bentwgB_Eps.h5"
927 bendFnEz = "./bentwgB_Ez.h5"
928 bendDielectricFile = prepareHDF5File(bendFnEps)
929 bendField.output_hdf5(Dielectric, bendVol.surroundings(), bendDielectricFile)
930
931 #create the file for the field components
932 bendFileOutputEz = prepareHDF5File(bendFnEz)
933
934 #define the flux plane for the reflected flux
935 bendReflectedfluxPlaneXPos = 1.5 #the X-coordinate of our reflection flux plane
936 bendReflectedFluxPlane = volume(vec(bendReflectedfluxPlaneXPos,wgHorYCen-wgWidth),vec(bendReflectedfluxPlaneXPos,wgHorYCen+wgWidth))
937 bendReflectedFlux = bendField.add_dft_flux_plane(bendReflectedFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100)
938
939 #load the minused reflection flux from the "no bend" case as initalization
940 bendReflectedFlux.load_hdf5(bendField, "minusflux")
941
942
943 #define the flux plane for the transmitted flux
944 bendTransmfluxPlaneYPos = padSize + wgLengthY - 1.5; #the Y-coordinate of our transmission flux plane
945 bendTransmFluxPlane = volume(vec(wgVerXCen - wgWidth,bendTransmfluxPlaneYPos),vec(wgVerXCen + wgWidth,bendTransmfluxPlaneYPos))
946 bendTransmFlux = bendField.add_dft_flux_plane(bendTransmFluxPlane, srcFreqCenter-(srcPulseWidth/2.0), srcFreqCenter+(srcPulseWidth/2.0), 100 )
947
948 master_printf("Calculating...")
949 bendProbingpoint = vec(wgVerXCen,bendTransmfluxPlaneYPos) #the point at the end of the waveguide that we want to probe to check if source has decayed
950 runUntilFieldsDecayed(bendField, bendVol, srcComp, bendProbingpoint, bendFileOutputEz)
951 master_printf("Done..!")
952
953 #construct 2-dimensional array with the flux plane data
954 #see python_meep.py
955 bendReflFlux = getFluxData(bendReflectedFlux)
956 bendTransmFlux = getFluxData(bendTransmFlux)
957
958 del_EPS_Callback()
959
960 #SHOW THE RESULTS IN A PLOT
961 frequencies = bendReflFlux[0] #should be equal to bendTransmFlux.keys() or noBendTransmFlux.keys() or ...
962 Ptrans = [x / y for x,y in zip(bendTransmFlux[1], noBendTransmFlux[1])]
963 Prefl = [ abs(x / y) for x,y in zip(bendReflFlux[1], noBendTransmFlux[1]) ]
964 Ploss = [ 1-x-y for x,y in zip(Ptrans, Prefl)]
965
966 matplotlib.pyplot.plot(frequencies, Ptrans, 'bo')
967 matplotlib.pyplot.plot(frequencies, Prefl, 'ro')
968 matplotlib.pyplot.plot(frequencies, Ploss, 'go' )
969
970 matplotlib.pyplot.show()
971
972
973
9748.3 With an inline C++ class as EPS-function
975______________________________________________
976
977
978The header file "eps_class.hpp" :
979
980
981::
982
983
984 using namespace meep;
985
986 namespace meep
987 {
988
989 class myEpsCallBack : virtual public Callback {
990
991 public:
992 myEpsCallBack() : Callback() { };
993 ~myEpsCallBack() { cout << "Callback object destructed." << endl; };
994
995 myEpsCallBack(bool isWgBent,double upperLimitHorizontalWg, double leftLimitVerticalWg, double lowerLimitHorizontalWg, double wgLengthX) : Callback() {
996 _IsWgBent = isWgBent;
997 _upperLimitHorizontalWg = upperLimitHorizontalWg;
998 _leftLimitVerticalWg = leftLimitVerticalWg;
999 _lowerLimitHorizontalWg = lowerLimitHorizontalWg;
1000 _wgLengthX = wgLengthX;
1001 };
1002
1003 double double_vec(const vec &v) {
1004 double eps = myEps(v, _IsWgBent, _upperLimitHorizontalWg, _leftLimitVerticalWg, _lowerLimitHorizontalWg, _wgLengthX);
1005 //cout << "X="<<v.x()<<"--Y="<<v.y()<<"--eps="<<eps<<"-"<<_upperLimitHorizontalWg<<"--"<<_leftLimitVerticalWg<<"--"<<_lowerLimitHorizontalWg<<"--"<<_wgLengthX;
1006 return eps;
1007 };
1008
1009 complex<double> complex_vec(const vec &x) { return 0; };
1010 complex<double> complex_time(const double &t) { return 0; };
1011
1012
1013 private:
1014 bool _IsWgBent;;
1015 double _upperLimitHorizontalWg;
1016 double _leftLimitVerticalWg;
1017 double _lowerLimitHorizontalWg;
1018 double _wgLengthX;
1019
1020 double myEps(const vec &v, bool isWgBent, double upperLimitHorizontalWg, double leftLimitVerticalWg, double lowerLimitHorizontalWg, double wgLengthX) {
1021 double xCo = v.x();
1022 double yCo = v.y();
1023 if (isWgBent){ //there is a bend
1024 if ((yCo < upperLimitHorizontalWg) || (xCo>wgLengthX)){
1025 return 1.0;
1026 }
1027 else {
1028 if ((xCo < leftLimitVerticalWg) && (yCo > lowerLimitHorizontalWg)) {
1029 return 1.0;
1030 }
1031 else {
1032 return 12.0;
1033 }
1034 }
1035 }
1036 else { //there is no bend
1037 if ((yCo < upperLimitHorizontalWg) || (yCo > lowerLimitHorizontalWg)){
1038 return 1.0;
1039 }
1040 }
1041 return 12.0;
1042 }
1043
1044 };
1045
1046 }
1047
1048
1049The Python program :
1050
1051
1052::
1053
1054
1055 from meep import *
1056
1057 from math import *
1058 import numpy
1059 import matplotlib.pyplot
1060 import sys
1061
1062 from scipy.weave import *
1063
1064 res = 10.0
1065 gridSizeX = 16.0
1066 gridSizeY = 32.0
1067 padSize = 4.0
1068 wgLengthX = gridSizeX - padSize
1069 wgLengthY = gridSizeY - padSize
1070 wgWidth = 1.0 #width of the waveguide
1071 upperLimitHorizontalWg = padSize
1072 lowerLimitHorizontalWg = padSize+wgWidth
1073 leftLimitVerticalWg = wgLengthX-wgWidth
1074 wgHorYCen = padSize + wgWidth/2.0 #horizontal waveguide center Y-pos
1075 wgVerXCen = wgLengthX - wgWidth/2.0 #vertical waveguide center X-pos (in case there is a bend)
1076 srcFreqCenter = 0.15 #gaussian source center frequency
1077 srcPulseWidth = 0.1 #gaussian source pulse width
1078 srcComp = Ez #gaussian source component
1079
1080
1081 def initEPS():
1082 #the set of parameters that we want to pass to the Callback object upon construction
1083 c_params = ['isWgBent','upperLimitHorizontalWg','leftLimitVerticalWg','lowerLimitHorizontalWg','wgLengthX'] #all these variables must be globally declared in the scope where the "inline" function call happens
1084 #the C-code snippet for constructing the Callback object
1085 c_code = prepareCallbackCObjectCode("myEpsCallBack", c_params)
1086 #do the actual inline C-call and fetch the pointer to the Callback object
1087 funPtr = inline(c_code,c_params, libraries=getInlineLibraries(), include_dirs = getInlineInclude(), headers = getInlineHeaders("eps_class.hpp") )
1088 #set the pointer to the callback object in the Python-meep core
1089 set_EPS_CallbackInlineObject(funPtr)
1090 print "EPS function successfully set."
1091 return
1092
1093 def createField(pCompVol, pWgLengthX, pWgWidth, pIsWgBent, pSrcFreqCenter, pSrcPulseWidth, pSrcComp):
1094 #we create a structure with PML of thickness = 1.0 on all boundaries,
1095 #in all directions,
1096 #using the material function EPS
1097 s = structure(pCompVol, EPS, pml(1.0) )
1098 f = fields(s)
1099 #define a gaussian line source of length 'wgWidth' at X=wgLength/2, Y=padSize
1100 srcGaussian = gaussian_src_time(pSrcFreqCenter, pSrcPulseWidth )
1101 srcGeo = volume(vec(1.0,padSize),vec(1.0,padSize+pWgWidth))
1102 f.add_volume_source(pSrcComp, srcGaussian, srcGeo, 1)
1103 print "Field created..."
1104 return f
1105
1106 master_printf("BENT WAVEGUIDE SAMPLE WITH INLINE C++ CLASS FOR EPS\n")
1107
1108 master_printf("Running on %d processor(s)...\n",count_processors())
1109
1110 #FIRST WE WORK OUT THE CASE WITH NO BEND
1111 #----------------------------------------------------------------
1112 master_printf("*1* Starting the case with no bend...")
1113
1114 #set EPS material function
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches