forked from rikigigi/analisi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
correlatorespaziale.cpp
129 lines (109 loc) · 4.13 KB
/
correlatorespaziale.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/**
*
* (c) Riccardo Bertossa, 2019
*
* Use at your own risk.
*
* If you modified the code, I could be happy if you contribute on github!
*
**/
#include <cmath>
#include<thread>
#include "correlatorespaziale.h"
#include "traiettoria.h"
#include "operazionisulista.h"
#include "config.h"
#define PI 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628
CorrelatoreSpaziale::CorrelatoreSpaziale(Traiettoria *t,
std::vector< std::array<double,3> > ks,
double sigma2,
unsigned int nthreads,
unsigned int skip,
bool debug) :
t{t},sfac(nullptr), sigma2(sigma2),debug(debug),tipi_atomi(0),ntimesteps(0), CalcolaMultiThread<CorrelatoreSpaziale> (nthreads,skip)
{
nk=ks.size();
klist=ks;
size_k=0;
size_sfac=0;
}
void CorrelatoreSpaziale::reset(const unsigned int numeroTimestepsPerBlocco) {
if (ntimesteps>=numeroTimestepsPerBlocco && t->get_ntypes()>=tipi_atomi){
ntimesteps=numeroTimestepsPerBlocco;
return;
}
delete [] sfac;
delete [] lista;
tipi_atomi=t->get_ntypes();
ntimesteps=numeroTimestepsPerBlocco;
size_k=3*tipi_atomi*2;// (complex number)
size_sfac=size_k*nk;
lunghezza_lista=ntimesteps*size_sfac/skip;
sfac = new double[size_sfac*nthreads];
lista = new double[lunghezza_lista];
}
std::vector<ssize_t> CorrelatoreSpaziale::get_shape() const{
return {ntimesteps/skip,nk,tipi_atomi,3,2};
}
std::vector<ssize_t> CorrelatoreSpaziale::get_stride() const{
return {static_cast<long>(sizeof(double)*size_sfac),
static_cast<long>(sizeof(double)*size_k),
sizeof(double)*2*3,
sizeof(double)*2,
sizeof(double)};
}
void CorrelatoreSpaziale::s_fac_k(const double k[3],
const unsigned int i_t,
double *out1 ///size 3*type {(x,y,z)_1, ..., (x,y,z)_ntype}
) const {
for (unsigned int i_at=0;i_at<t->get_natoms();i_at++){
const double * pos = t->posizioni(i_t,i_at);
const double * vel = t->velocita(i_t,i_at);
unsigned int type=t->get_type(i_at);
double arg=k[0]*pos[0]+k[1]*pos[1]+k[2]*pos[2];
double s=sin(arg),c=cos(arg);
for (unsigned int icoord=0;icoord<3;icoord++){
out1[3*type*2+icoord*2+0]+=c*vel[icoord];
out1[3*type*2+icoord*2+1]+=s*vel[icoord];
}
}
}
void CorrelatoreSpaziale::calc_single_th(const unsigned int &start, const unsigned int &stop, const unsigned int &primo, const unsigned int &ith) noexcept {
double * sfact=&sfac[size_sfac*ith];
int ilista=(start-primo)/skip;
for (unsigned int itimestep=start;itimestep<stop;itimestep+=skip){
//calculate at itimestep in lista ad itimestep+1 in sfac. Then put in itimestep the difference
//loop over k
int ik=0;
for (unsigned int i=0;i<size_sfac;i++) {
sfact[i]=0.0;
}
for (unsigned int i=0;i<size_sfac;i++) {
lista[size_sfac*ilista+i]=0.0;
}
for (auto &k : klist){
double kmod=sqrt(k[0]*k[0]+k[1]*k[1]+k[2]*k[2]);
if (kmod == 0) kmod=1.0;
s_fac_k(k.data(),itimestep,&lista[size_sfac*ilista+ik*size_k]);
s_fac_k(k.data(),itimestep+1,&sfact[ik*size_k]);
//put the difference inside lista
for (unsigned int i=0;i<size_k;i++){
lista[size_sfac*ilista+ik*size_k+i]=(sfact[ik*size_k+i]-lista[size_sfac*ilista+ik*size_k+i])/kmod;
}
++ik;
}
ilista++;
}
} // end calcola
void CorrelatoreSpaziale::print(std::ostream &out){
//print stuff
for (unsigned int i=0;i<ntimesteps/skip;++i){
for (unsigned int j=0;j<size_sfac;++j){
out << lista[i*size_sfac+j]<<" ";
}
out << std::endl;
}
}
CorrelatoreSpaziale::~CorrelatoreSpaziale(){
delete [] sfac;
}