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

A Request for Intermediate Scattering function #1040

Open
Roy-Kid opened this issue Nov 25, 2022 · 4 comments · May be fixed by #1042
Open

A Request for Intermediate Scattering function #1040

Roy-Kid opened this issue Nov 25, 2022 · 4 comments · May be fixed by #1042
Labels
enhancement New feature or request

Comments

@Roy-Kid
Copy link

Roy-Kid commented Nov 25, 2022

Description

The intermediate scattering function is defined as the Fourier transform of the Van Hove function:
image
Instead of Fourier transform, these functions can also be directly computed from the atomic trajectories:
image
Fs and Fd are self and distinct parts.

Is there any plan to support this function? Otherwise, I can write one following structure factor code and MSD part.

Proposed Solution

isf = freud.Scattering.Intermedidate(k_space, ...)
# points = (N_frames, N_particles, 3)
# points = (N_frames, M_particles, 3)
isf.compute((box, points)).query(query_points)
isf.self_part
isf.distinct_part

Additional Context

Reference:
https://www.lehigh.edu/imi/teched/AtModel/Lecture_11_Micoulaut_Atomistics_Glass_Course.pdf

Developer

Would someone else please implement this?

@Roy-Kid Roy-Kid added the enhancement New feature or request label Nov 25, 2022
@tommy-waltmann
Copy link
Collaborator

This seems like a reasonable feature to add to freud. This function has a time-dependence to it. We have only one other analysis, MSD, in freud which computes a function with explicit time dependence, so the API should mirror that and take the box as a parameter to the constructor, and then give a 3-dimensional array of positions to the compute method.

In addition, it will be important to average over k-vectors properly. A good example to work from is in the StaticStructureFactorDirect class.

With all of those things in mind, here's how I would propose the new class to look, along with all the properties that make sense to expose:

isf = freud.diffraction.IntermediateScattering(box, k_max, k_min, num_sampled_k_points)
isf.compute(points, query_points, N_total, reset)

# access properties
isf.k_max
isf.k_min
isf.k_points
isf.nbins
isf.num_sampled_k_points
isf.min_valid_k
isf.bounds
isf.bin_edges
isf.bin_centers

isf.self_function
isf.distinct_function

The query_points and N_total in the compute method are only needed when computing partial scattering functions. It would be completely okay to ignore that and just compute full scattering functions in a PR that creates the class, then come back later and implement partials only if necessary.

@Roy-Kid How comfortable would you be trying to implement this yourself? It's not a simple calculation to write, but I would be able to assist to get past roadblocks in implementation.

@Roy-Kid
Copy link
Author

Roy-Kid commented Nov 29, 2022

Thanks for your concern.
I have started to read the source code of StaticStructureFactorDirect and msd and hope to combine those together. I think the difficulty is to understand the code about how to contracture reciprocal space.

I am try to do this work, but i'm not sure I can complete or give a robust code.

@tommy-waltmann
Copy link
Collaborator

Okay. The sampling of reciprocal space is done in StaticStructureFactorDirect::reciprocal_isotropic, that code should actually be reused for this new feature, because the sampling method will be the same.

When I have the time, I can assist with getting some of the boilerplate code and class structure in place first and then we can work more on implementation from after that.

@Roy-Kid Roy-Kid linked a pull request Nov 30, 2022 that will close this issue
8 tasks
@Roy-Kid
Copy link
Author

Roy-Kid commented Nov 30, 2022

@tommy-waltmann
Hi waltmann,

I start a PR as a start for intermediate scattering calculation. I write boilerplate code for both python and c++. Here is my plan:

  1. We derive/extend the StaticStructureFactorDirect class to use reciprocal_isotropic compute_F_k etc.
  2. Since the isf is time-dependent and reply on r(t=0), so we record the position of first frame, and construct a neighborlist by AABQUERY((box, point)).query(r(t=0)).
  3. The neighborlist computes the all distance between all particles and there should be a method to separate "self-distance" and "distinct-distance" (I think it can be done by the construct a index filter).
  4. When we get the r_i_t - r_i_t0 and r_i_t - r_j_t0, we can reuse the compute_F_k to compute exponent factor.
  5. To compute F(k, t), we need to pass all frames to compute method in python like what MSD does. The inner for loop accumulate the isf result one-by-one frame.
  6. Finally we get a (n_frame, n_k) array for both self and distinct function.

What do you think? Please indicate any physical errors or code-style differences.

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

Successfully merging a pull request may close this issue.

2 participants