orientorder/atom dot product histogram

Dear lammps community,

I would like to be able to output histograms of the dot product of the Ql order parameters generated by the compute orientorder/atom command. I found that compute coord/atom is capable of counting connections based on the dot products I require and therefore are already calculating them. So my idea was to make a new compute almost identical to compute_coord_atom’s orientorder claculation, but instead of generating a per atom scalar quantity with the number of connections per atom, it would generate a vector that simply stores all of the calculated dot product values. That way, the result can be used with fix ave/histo to generate the histograms and also average over timesteps as desired.

My question is, is this the best way to achieve what I need, and if so, how should I handle the memory allocation of the output vector? I noticed that computes that aren’t per atom define the size of the vector/array in the constructor function. In this case the size of the vector seems best decided dynamically since it depends on the total # of neighbors that are within a cutoff for each atom in the group. I am thinking of using a c++ style dynamic vector to store all the values using push_back() and then copy the contents to my output vector with its size declared near the end, equal to the final size of the dynamic vector. Would something like this work, or is declaring the size of the output vector beforehand in the constructor an absolute requirement?

Thank you,
Abdullah

Dear lammps community,

I would like to be able to output histograms of the dot product of the Ql
order parameters generated by the compute orientorder/atom command. I found
that compute coord/atom is capable of counting connections based on the dot
products I require and therefore are already calculating them. So my idea
was to make a new compute almost identical to compute_coord_atom's
orientorder claculation, but instead of generating a per atom scalar
quantity with the number of connections per atom, it would generate a
vector that simply stores all of the calculated dot product values. That
way, the result can be used with fix ave/histo to generate the histograms
and also average over timesteps as desired.

​that approach will blow up the ​required storage and communication (as
well as non-parallel code) significantly. i would propose, you compile the
histogram directly on each processor, then you can do an MPI_Allreduce() to
collect the histogram and return this as a fixed size global vector, when
can then be accumulated over time with fix ave/time.

My question is, is this the best way to achieve what I need, and if so,
how should I handle the memory allocation of the output vector? I noticed
that computes that aren't per atom define the size of the vector/array in
the constructor function. In this case the size of the vector seems best
decided dynamically since it depends on the total # of neighbors that are
within a cutoff for each atom in the group. I am thinking of using a c++
style dynamic vector to store all the values using push_back() and then
copy the contents to my output vector with its size declared near the end,
equal to the final size of the dynamic vector. Would something like this
work, or is declaring the size of the output vector beforehand in the
constructor an absolute requirement?

​using STL containers for storage that has to be passed on as a pointer, is
usually not a good idea. to be safe, it will always require additional
copying.
also, having storage that has to be of a size of a large number times the
number of atoms, is to be avoided​. this can quickly "explode" when running
in parallel and on large systems, as you'll have to have that storage
combined and communicated across all processors. my proposal from above
should avoid many of these issues, as you now have only 1 fixed size
histogram per MPI rank which will then be combined through MPI using a
reduction.

​axel.​

I see, thank you for the suggestion. Compiling local histograms was my original thought but that wouldn’t have worked with fix ave/histo. I didn’t think of using fix ave/time! In that case do you think it would be useful to add a “histo” optional arg to the orientorder cstyle of compute coord/atom command, that would produce a global vector histogram in addition to the per-atom quantities? I read in the compute manual that a few computes do generate more than one style of quantities but am not aware which ones specifically. If anyone is familiar with one and could point me to it, I’d be grateful to look at its code as an example.

The other question this would raise, is how fix ave/time would access the global vector as opposed to the per-atom quantity since I believe it expects a compute that produces either a scalar or vector quantity. If a compute produces both, is there a way to tell fix ave/time which to access? Otherwise I’ll just do it as a separate compute.

Thank you,
Abdullah