-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtemperature_density_pdf2d.cpp
155 lines (132 loc) · 5.4 KB
/
temperature_density_pdf2d.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <iomanip>
#include <fstream>
#include <sstream>
#include <MultiFab.H>
#include <Geometry.H>
#include <BLFort.H>
BL_FORT_PROC_DECL(CALC_PDF2D, calc_pdf2d) (
const Real* temperature,
const Real* density,
const int* lo,
const int* hi,
const int* num_ghosts,
const int* tpdf_num_bins,
const int* dpdf_num_bins,
const Real* t_bin_edges,
const Real* d_bin_edges,
const int* bin_count,
const Real* bin_t_sum,
const Real* bin_d_sum);
void temperature_density_pdf2d (const MultiFab& temperature,
const MultiFab& density,
const Geometry &geom,
const Real mean_density,
const unsigned int nStep)
{
MultiFab overdensity(density.boxArray(), 1, 0);
overdensity.copy(density);
overdensity.mult(1.0/mean_density);
overdensity.plus(-1.0, 0, 1);
#warning TODO: make temperature PDF knobs run-time parameters
const Real log10_t_min = 3.0;
const Real log10_t_max = 8.0;
const int tpdf_num_bins = 400;
#warning TODO: make density PDF knobs run-time parameters
const Real log10_d_min = -2.0;
const Real log10_d_max = 5.0;
const int dpdf_num_bins = 400;
const int temperature_num_ghosts = temperature.nGrow();
// These are counts per *process*, not per *box*. We'll AllReduce() them
// after iterating over all boxes.
std::vector<int> bin_count;
std::vector<Real> bin_t_sum;
std::vector<Real> bin_d_sum;
std::vector<Real> bin_edges_t;
std::vector<Real> bin_edges_d;
const unsigned int num_bins = tpdf_num_bins*dpdf_num_bins;
bin_count.resize(num_bins);
bin_t_sum.resize(num_bins);
bin_d_sum.resize(num_bins);
for (unsigned int i = 0; i < num_bins; ++i) {
bin_count[i] = 0;
bin_t_sum[i] = 0.0;
bin_d_sum[i] = 0.0;
}
bin_edges_t.resize(tpdf_num_bins+1);
Real bin_width = (log10_t_max - log10_t_min) / Real(tpdf_num_bins);
for (unsigned int i = 0; i <= tpdf_num_bins; ++i) {
bin_edges_t[i] = std::pow(10.0, log10_t_min + Real(i)*bin_width);
}
bin_edges_d.resize(dpdf_num_bins+1);
bin_width = (log10_d_max - log10_d_min) / Real(dpdf_num_bins);
for (unsigned int i = 0; i <= dpdf_num_bins; ++i) {
bin_edges_d[i] = std::pow(10.0, log10_d_min + Real(i)*bin_width);
}
for ( MFIter mfi(temperature); mfi.isValid(); ++mfi ) {
const Box& bx = mfi.validbox();
// These are counts per *box*. We'll glob them all together after
// iterating over all boxes.
std::vector<int> bin_count_per_box(num_bins);
std::vector<Real> bin_t_sum_per_box(num_bins);
std::vector<Real> bin_d_sum_per_box(num_bins);
BL_FORT_PROC_CALL(CALC_PDF2D, calc_pdf2d) (
(temperature)[mfi].dataPtr(),
(overdensity)[mfi].dataPtr(),
bx.loVect(),
bx.hiVect(),
&temperature_num_ghosts,
&tpdf_num_bins,
&dpdf_num_bins,
&bin_edges_t[0],
&bin_edges_d[0],
&bin_count_per_box[0],
&bin_t_sum_per_box[0],
&bin_d_sum_per_box[0]);
// Accumulate per-box results into per-process arrays
for (unsigned int i = 0; i < num_bins; ++i) {
bin_count[i] += bin_count_per_box[i];
bin_t_sum[i] += bin_t_sum_per_box[i];
bin_d_sum[i] += bin_d_sum_per_box[i];
}
}
ParallelDescriptor::ReduceIntSum (&bin_count[0], num_bins);
ParallelDescriptor::ReduceRealSum(&bin_t_sum[0], num_bins);
ParallelDescriptor::ReduceRealSum(&bin_d_sum[0], num_bins);
// Normalization
Real sum_ni_dai = 0.0;
for (unsigned int i = 0; i < tpdf_num_bins; ++i) {
for (unsigned int j = 0; j < dpdf_num_bins; ++j) {
const unsigned idx = j + (i*dpdf_num_bins);
Real dx_i = bin_edges_t[i+1] - bin_edges_t[i];
Real dx_j = bin_edges_d[j+1] - bin_edges_d[j];
sum_ni_dai += bin_count[idx] * dx_i * dx_j;
}
}
// Normalization constant for N_i -> P_i
Real pnorm = 1.0 / sum_ni_dai;
std::vector<Real> bin_x(num_bins);
std::vector<Real> bin_y(num_bins);
std::vector<Real> bin_p(num_bins);
for (unsigned int i = 0; i < num_bins; ++i) {
if (bin_count[i] > 0) {
bin_x[i] = bin_t_sum[i] / Real(bin_count[i]);
bin_y[i] = bin_d_sum[i] / Real(bin_count[i]);
bin_p[i] = pnorm * Real(bin_count[i]);
}
}
if (ParallelDescriptor::IOProcessor()) {
std::ofstream temperature_pdf_output_file;
std::stringstream filename;
filename << "rhot_pdf2d_nstep_" << std::setfill('0') << std::setw(5) << nStep;
temperature_pdf_output_file.open(filename.str().c_str());
temperature_pdf_output_file << std::scientific;
for (unsigned int i = 0; i < dpdf_num_bins; ++i) {
for (unsigned int j = 0; j < tpdf_num_bins; ++j) {
const unsigned int idx = j + (i*tpdf_num_bins);
temperature_pdf_output_file << std::setw(35) << bin_edges_d[i] << std::setw(35) << bin_edges_t[j] << std::setw(15) << bin_count[idx] << std::setw(15) << bin_x[idx] << std::setw(15) << bin_y[idx] << std::setw(15) << bin_p[idx] << std::endl;
}
}
temperature_pdf_output_file.close();
}
return;
}