Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

abort with error message when fields have diverged #916

Closed
oskooi opened this issue Jun 13, 2019 · 1 comment · Fixed by #922
Closed

abort with error message when fields have diverged #916

oskooi opened this issue Jun 13, 2019 · 1 comment · Fixed by #922

Comments

@oskooi
Copy link
Collaborator

oskooi commented Jun 13, 2019

Under certain circumstances, the fields are known to diverge (i.e., blow up). For certain jobs e.g. those launched in the background where the fields are not actively monitored, this field divergence may go unnoticed until the end of the run when field-derived quantities such as Poynting flux, mode coefficients (S-parameters), quality factors, etc are computed. Rather than unnecessarily waste resources time-stepping to completion a simulation with meaningless results, it would be useful if Meep would immediately abort with an error if the fields (say, at the source location) are greater than some threshold value (e.g., 1e20). There could even be a boolean parameter e.g. abort_on_field_divergence passed to the Simulation constructor which is False by default and would merely output a warning message (but not abort) to alert the user so they can decide what to do.

As a demonstration, the following example defines a negative, wavelength-independent permittivity as the default_material in a 2d cell and outputs the energy density at fixed time intervals.

import meep as mp

resolution = 20

cell_size = mp.Vector3(5,5)

k_point = mp.Vector3()

sources = [mp.Source(mp.GaussianSource(1.0,fwidth=0.1),
                     center=mp.Vector3(0.396257,-0.809851),
                     component=mp.Ez)]

sim = mp.Simulation(resolution=resolution,
                    cell_size=cell_size,
                    k_point=k_point,
                    sources=sources,
                    default_material=mp.Medium(epsilon=-2.5))

def print_stuff(sim):
  p = sim.get_field_point(mp.Ez, mp.Vector3(-1.75,0.48))
  print("field:, {}, {}".format(sim.meep_time(), abs(p)**2))

sim.run(mp.at_every(0.3,print_stuff),
        until_after_sources=100)

Long before the termination condition is reached, the fields blow up and the simulation automatically terminates with an overflow error:

-----------
Initializing structure...
Working in 2D dimensions.
Computational cell is 5 x 5 x 0 with resolution 20
time for set_epsilon = 0.011915 s
-----------
field:, 0.30000000000000004, 0.0
field:, 0.6000000000000001, 0.0
field:, 0.9, 0.0
field:, 1.2000000000000002, 0.0
field:, 1.5, 0.0
field:, 1.8, 3.1957700588518584e-96
field:, 2.1, 3.0085898033257857e-66
field:, 2.4000000000000004, 1.1634761243755626e-43
field:, 2.7, 1.1967037249080024e-24
field:, 3.0, 5.647615689384338e-08
field:, 3.3000000000000003, 18450761.134028625
field:, 3.6, 1.982478458941253e+22
field:, 3.9000000000000004, 7.005758785294e+36
field:, 4.2, 2.136868981720534e+50
field:, 4.5, 1.4228700252524937e+63
field:, 4.800000000000001, 3.0138494696176103e+75
field:, 5.1000000000000005, 2.5608537001629185e+87
field:, 5.4, 1.0280293977575443e+99
field:, 5.7, 2.2044846333172146e+110
field:, 6.0, 2.7781493706514414e+121
field:, 6.300000000000001, 2.2200688133822762e+132
field:, 6.6000000000000005, 1.1964246635775624e+143
field:, 6.9, 4.5737800162412054e+153
field:, 7.2, 1.293520839322337e+164
field:, 7.5, 2.8032791063858083e+174
field:, 7.800000000000001, 4.795910720561794e+184
field:, 8.1, 6.643231886797671e+194
field:, 8.4, 7.613808659931723e+204
field:, 8.700000000000001, 7.355944644892065e+214
field:, 9.0, 6.088240446680256e+224
field:, 9.3, 4.377630484311144e+234
field:, 9.600000000000001, 2.768019089511036e+244
field:, 9.9, 1.555581482023388e+254
field:, 10.200000000000001, 7.84210412592441e+263
field:, 10.5, 3.575145551328443e+273
field:, 10.8, 1.4842939113280275e+283
field:, 11.100000000000001, 5.645935151047591e+292
field:, 11.4, 1.977774425677807e+302
Traceback (most recent call last):
  File "negative-eps.py", line 24, in <module>
    until_after_sources=100)
  File "/usr/local/lib/python3.5/site-packages/meep/simulation.py", line 2068, in run
    self._run_sources_until(until_after_sources, step_funcs)
  File "/usr/local/lib/python3.5/site-packages/meep/simulation.py", line 1362, in _run_sources_until
    self._run_until(new_conds, step_funcs)
  File "/usr/local/lib/python3.5/site-packages/meep/simulation.py", line 1330, in _run_until
    _eval_step_func(self, func, 'step')
  File "/usr/local/lib/python3.5/site-packages/meep/simulation.py", line 2299, in _eval_step_func
    func(sim, todo)
  File "/usr/local/lib/python3.5/site-packages/meep/simulation.py", line 2364, in _every
    _eval_step_func(sim, func, todo)
  File "/usr/local/lib/python3.5/site-packages/meep/simulation.py", line 2297, in _eval_step_func
    func(sim)
  File "negative-eps.py", line 21, in print_stuff
    print("field:, {}, {}".format(sim.meep_time(), abs(p)**2))
OverflowError: (34, 'Numerical result out of range')

Elapsed run time = 0.0278 s

In some situations, the fields do not blow up to such an extent so as to trigger an overflow error. Nevertheless, even in this example, the simulation should have been terminated much sooner.

@stevengj
Copy link
Collaborator

are greater than some threshold value (e.g., 1e20).

We really need to get rid of all these hard-coded usages of 1e20 for "infinity" in the code, and just check for isinf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants