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

Tmfp #12

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

Tmfp #12

wants to merge 13 commits into from

Conversation

atheulings
Copy link
Contributor

Merge branch tmfp to master in order to implement the calculation of the electron range used in Geant4.

@atheulings atheulings requested a review from lvkessel June 30, 2017 12:58
@lvkessel
Copy link
Contributor

lvkessel commented Jun 30, 2017

We are really calculating the inelastic imfp twice, which seems kind of pointless... but I suppose it fits in with the philosophy of cstool-is-a-library-not-an-application.

Anyway, I do have a few points:

  • It is probably nicer to use a function that simply integrates, without providing the icdf. Right now, you are using compute_tcs_icdf from cstool.compile, and throwing away the dummy icdf. That's OK for testing purposes, but unnecessary for production code.
  • Comments on lines 244, 245 are completely unrelated to the code that surrounds them. (OK, the relationship is a copy-paste thing, but the units don't even check out anymore)
  • Loop in lines 247 -- 257: this can be done in a more elegant / modern way. At least make sure that j, omega and omega_old only exist within the loop scope. For example, looping over for j in range(len(e_ran)), and breaking when e_ran[j] becomes too large, is generally considered "better". You could make things a lot nicer by using the syntax for j, omega in enumerate(e_ran). Then you still need to do something about omega_old, which is just e_ran[j-1] (unless j == 0). That relationship is not very clear from the code as it is right now.
  • Line 254: this can be replaced by +=.
  • You drop the units in lines 223 and 246, then reinsert them in line 263. Seems quite pointless (and very ugly) to me. Lines 227/228 should of course be multiplied by a length.

@lvkessel
Copy link
Contributor

Also, just a general thing: why do we always use 129 values along the energy axis? If it's just an arbitrary choice, why not pick a round number?

Luc van Kessel and others added 3 commits July 4, 2017 17:09
"dv1" is not really an acronym. The "1" is because it is a first attempt. The D is probably for Delft, and the V could perhaps mean "Version".
@atheulings
Copy link
Contributor Author

I have resolved all the comments on the code, please check this.

I do not know why we always use 129 values along the energy axis. Maybe @kerimarat or @slokhorst know?

Copy link
Contributor

@lvkessel lvkessel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I did a more line-by-line style review here. These are mostly style-related suggestions, but in some cases I suggest a significantly different program flow. Do as you wish though, these are just opinions.

tmprange[i] = 1/tcs
for j, omega in enumerate(e_ran):
if (omega < K/2 and omega < K-s.band_structure.fermi):
if j==0:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be more of a personal opinion, but I would prefer omega_old = 0 if j==0 else e_ran[j-1] here. These ternary operators tend to lead to excessively long lines, so one should be careful with them, but I think this is a case where it helps the code clarity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

s.elf_file.get_min_energy_interval())
tmprange[i] = 1/tcs
for j, omega in enumerate(e_ran):
if (omega < K/2 and omega < K-s.band_structure.fermi):
Copy link
Contributor

@lvkessel lvkessel Jul 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest the following:

if omega >= K/2 or omega >= K - s.band_structure.fermi:
    break

and no else clause for the actual code. This pattern is pretty common.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this comment is mostly related to the code that comes after it.

tmprange = np.zeros(e_ran.shape) * units.m
print("# Computing inelastic electron range.")
for i, K in enumerate(e_ran):
ran_energies[i] = K.to('eV')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this? Does supplying data=e_ran.to('eV') in line 217 not already do this?

if ( K >= s.band_structure.barrier):
# make sure the tmfp is monotonously increasing for energies above
# the vacuum potential barrier
if (tmfp < tmfpmax):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: tmfpmax = np.maximum(tmfp_max, tmfp) instead of these four lines and change line 239 to ran_tmfp[i] = tmfp_max.

So do not change the tmfp variable, conceptually it will always hold the tmfp for the current kinetic energy. Meanwhile, tmfp_max is the largest one you have found (bar anything below the vacuum barrier), and you make it clear that that's what you want to write to ran_tmfp.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"These four lines" relates to the line I commented on and the three lines BELOW it. github doesn't allow for multiline comments, sorry for the confusion.

@@ -23,6 +24,12 @@ def integrant(theta):

return compute_tcs_icdf(integrant, 0*units('rad'), np.pi*units('rad'), P)

def compute_elastic_tcs(dcs, P):
def integrant(theta):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you that we should be consistent in spelling "integrand" incorrectly.

@@ -6,6 +6,7 @@
from cstool.phonon import phonon_cs_fn
from cstool.inelastic import inelastic_cs_fn
from cstool.compile import compute_tcs_icdf
from cstool.compile import compute_tcs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two lines can be merged in one. Would make it more consistent with the other imports.

def compute_tcs(f, a, b, P, sampling=100000):
x = np.linspace(a, b.to(a.units), sampling) * a.units
y = f(x)
cf = np.r_[0, np.cumsum((x[1:] - x[:-1]) * (y[:-1] + y[1:]) / 2.0)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are still storing all intermediate integration results here, while you only need the last. Actually, since this is simply an n-point trapezoid rule, you could just return np.trapz(y, x) here -- shorter, intent is clear, and probably faster.

@lvkessel
Copy link
Contributor

lvkessel commented Jul 6, 2017

As for using 129 values, looking at the commit history it seems to have been introduced by @jhidding.

@slokhorst
Copy link
Contributor

The 129 energy values are just a random choice I think. In e-scatter, we use 1024 values, so I guess it would make sense to match that here.

@lvkessel
Copy link
Contributor

lvkessel commented Jul 6, 2017

At least 1024 is a round number. That lets me sleep better than 129.

As the lower energy bounds are different between cstool and e-scatter, there is no point in using 1024 here to "match" e-scatter. But I think we will all agree that cstool should provide at least the resolution that our simulator intends to use. Anyway, we're getting a bit off-topic here.

@slokhorst
Copy link
Contributor

Don't forget to fix #13 before/after merge

@lvkessel
Copy link
Contributor

Absolutely, thanks for creating that issue. If nobody else fixes it, I'll do it as soon as I get back. It's independent from the tmfp thing though.

@slokhorst
Copy link
Contributor

@lvkessel You're right. This shouldn't cause a merge conflict, so I've fixed it in the master branch: d111a3d.

@jhidding
Copy link
Contributor

At least 1024 is a round number. That lets me sleep better than 129.

As the lower energy bounds are different between cstool and e-scatter, there is no point in using 1024 here to "match" e-scatter. But I think we will all agree that cstool should provide at least the resolution that our simulator intends to use. Anyway, we're getting a bit off-topic here.

Historical reference: The 129 was probably chosen as (128 + 1), creating more or less round numbers, since the end-point of the interval is also included in the range.

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

Successfully merging this pull request may close these issues.

4 participants