/home/users/khuck/src/octotiger/src/grid_output.cpp

Line% of fetchesSource
1  
#include "grid.hpp"
2  
#ifdef DO_OUTPUT
3  
#include <silo.h>
4  
#endif
5  
#include <fstream>
6  
#include <thread>
7  
#include <cmath>
8  
9  
#include <hpx/include/lcos.hpp>
10  
//#define EQ_ONLY
11  
//#define RHO_ONLY
12  
13  
namespace hpx {
14  
using mutex = hpx::lcos::local::spinlock;
15  
}
16  
17  
std::vector<std::vector<real>>& TLS_V();
18  
19  
#include <unordered_map>
20  
21  
inline bool float_eq(xpoint_type a, xpoint_type b) {
22  
    constexpr static xpoint_type eps = 0.00000011920928955078125; // std::pow(xpoint_type(2), -23);
23  
// 	const xpoint_type eps = std::pow(xpoint_type(2), -23);
24  
    return std::abs(a - b) < eps;
25  
}
26  
27  
bool grid::xpoint_eq(const xpoint& a, const xpoint& b) {
28  
    bool rc = true;
29  
    for (integer d = 0; d != NDIM; ++d) {
30  
        if (!float_eq(a[d], b[d])) {
31  
            rc = false;
32  
            break;
33  
        }
34  
    }
35  
    return rc;
36  
}
37  
38  
bool grid::node_point::operator==(const node_point& other) const {
39  
    return xpoint_eq(other.pt, pt);
40  
}
41  
42  
bool grid::node_point::operator<(const node_point& other) const {
43  
    bool rc = false;
44  
    for (integer d = 0; d != NDIM; ++d) {
45  
        if (!float_eq(pt[d], other.pt[d])) {
46  
            rc = (pt[d] < other.pt[d]);
47  
            break;
48  
        }
49  
    }
50  
    return rc;
51  
}
52  
53  
void grid::merge_output_lists(grid::output_list_type& l1, grid::output_list_type&& l2) {
54  
55  
    std::unordered_map<zone_int_type, zone_int_type> index_map;
56  
57  
    if (l2.zones.size() > l1.zones.size()) {
58  
        std::swap(l1, l2);
59  
    }
60  
    for (auto i = l2.nodes.begin(); i != l2.nodes.end(); ++i) {
61  
        zone_int_type index, oindex;
62  
        auto this_x = *i;
63  
        oindex = this_x.index;
64  
        auto j = l1.nodes.find(this_x);
65  
        if (j != l1.nodes.end()) {
66  
            index = j->index;
67  
        } else {
68  
            index = l1.nodes.size();
69  
            this_x.index = index;
70  
            l1.nodes.insert(this_x);
71  
        }
72  
        index_map[oindex] = index;
73  
    }
74  
    integer zzz = l1.zones.size();
75  
    l1.zones.resize(zzz + l2.zones.size());
76  
    for (auto i = l2.zones.begin(); i != l2.zones.end(); ++i) {
77  
        l1.zones[zzz] = index_map[*i];
78  
        ++zzz;
79  
    }
80  
    for (integer field = 0; field < NF + NGF + NPF; ++field) {
81  
        const auto l1sz = l1.data[field].size();
82  
        l1.data[field].resize(l1sz + l2.data[field].size());
83  
        std::move(l2.data[field].begin(), l2.data[field].end(), l1.data[field].begin() + l1sz);
84  
    }
85  
    if (l1.analytic.size()) {
86  
        for (integer field = 0; field < NF; ++field) {
87  
            const auto l1sz = l1.analytic[field].size();
88  
            l1.analytic[field].resize(l1sz + l2.analytic[field].size());
89  
            std::move(l2.analytic[field].begin(), l2.analytic[field].end(), l1.analytic[field].begin() + l1sz);
90  
        }
91  
    }
92  
}
93  
94  
grid::output_list_type grid::get_output_list(bool analytic) const {
95  
    auto& V = TLS_V();
96  
    compute_primitives();
97  
    output_list_type rc;
98  
    const integer vertex_order[8] = { 0, 1, 3, 2, 4, 5, 7, 6 };
99  
100  
    std::set<node_point>& node_list = rc.nodes;
101  
    std::vector<zone_int_type>& zone_list = rc.zones;
102  
    std::array<std::vector<real>, NF + NGF + NPF> &data = rc.data;
103  
    std::array<std::vector<real>, NF + NGF + NPF> &A = rc.analytic;
104  
105  
    for (integer field = 0; field != NF + NGF + NPF; ++field) {
106  
        data[field].reserve(INX * INX * INX);
107  
        if (analytic) {
108  
            A[field].reserve(INX * INX * INX);
109  
        }
110  
    }
111  
    const integer this_bw = H_BW;
112  
    zone_list.reserve(cube(H_NX - 2 * this_bw) * NCHILD);
113  
    for (integer i = this_bw; i != H_NX - this_bw; ++i) {
114  
        for (integer j = this_bw; j != H_NX - this_bw; ++j) {
115  
            for (integer k = this_bw; k != H_NX - this_bw; ++k) {
116  
                const integer iii = hindex(i, j, k);
117  
                const integer iiig = gindex(i - H_BW, j - H_BW, k - H_BW);
118  
#ifdef EQ_ONLY
119  
                if (!(std::abs(X[ZDIM][iii]) < dx) && !(std::abs(X[YDIM][iii]) < dx)) {
120  
                    continue;
121  
                }
122  
#endif
123  
                for (integer ci = 0; ci != NVERTEX; ++ci) {
124  
                    const integer vi = vertex_order[ci];
125  
                    const integer xi = (vi >> 0) & 1;
126  
                    const integer yi = (vi >> 1) & 1;
127  
128  
                    const integer zi = (vi >> 2) & 1;
129  
                    node_point this_x;
130  
                    this_x.pt[XDIM] = X[XDIM][iii] + (real(xi) - HALF) * dx;
131  
                    this_x.pt[YDIM] = X[YDIM][iii] + (real(yi) - HALF) * dx;
132  
                    this_x.pt[ZDIM] = X[ZDIM][iii] + (real(zi) - HALF) * dx;
133  
                    auto iter = node_list.find(this_x);
134  
                    integer index;
135  
                    if (iter != node_list.end()) {
136  
                        index = iter->index;
137  
                    } else {
138  
                        index = node_list.size();
139  
                        this_x.index = index;
140  
                        node_list.insert(this_x);
141  
                    }
142  
                    zone_list.push_back(index);
143  
                }
144  
                if (analytic) {
145  
                    for (integer field = 0; field != NF; ++field) {
146  
                        A[field].push_back(Ua[field][iii]);
147  
                    }
148  
                }
149  
                for (integer field = 0; field != NF; ++field) {
150  
                    data[field].push_back(U[field][iii]);
151  
                }
152  
                for (integer field = 0; field != NGF; ++field) {
153  
                    data[field + NF].push_back(G[iiig][field]);
154  
                }
155  
                data[NGF + NF + 0].push_back(V[vx_i][iii]);
156  
                data[NGF + NF + 1].push_back(V[vy_i][iii]);
157  
                data[NGF + NF + 2].push_back(V[vz_i][iii]);
158  
                if (V[egas_i][iii] * V[rho_i][iii] < de_switch2 * U[egas_i][iii]) {
159  
                    data[NGF + NF + 3].push_back(std::pow(V[tau_i][iii], fgamma) / V[rho_i][iii]);
160  
                } else {
161  
                    data[NGF + NF + 3].push_back(V[egas_i][iii]);
162  
                }
163  
                data[NGF + NF + 4].push_back(V[zz_i][iii]);
164  
            }
165  
        }
166  
    }
167  
168  
    return rc;
169  
}
170  
171  
void grid::output(const output_list_type& olists, std::string _filename, real _t, int cycle, bool analytic) {
172  
#ifdef DO_OUTPUT
173  
174  
    std::thread(
175  
            [&](const std::string& filename, real t) {
176  
                printf( "t = %e\n", t);
177  
                const std::set<node_point>& node_list = olists.nodes;
178  
                const std::vector<zone_int_type>& zone_list = olists.zones;
179  
180  
                const int nzones = zone_list.size() / NVERTEX;
181  
                std::vector<int> zone_nodes;
182  
                zone_nodes = std::move(zone_list);
183  
184  
                const int nnodes = node_list.size();
185  
                std::vector<double> x_coord(nnodes);
186  
                std::vector<double> y_coord(nnodes);
187  
                std::vector<double> z_coord(nnodes);
188  
                std::array<double*, NDIM> node_coords = {x_coord.data(), y_coord.data(), z_coord.data()};
189  
                for (auto iter = node_list.begin(); iter != node_list.end(); ++iter) {
190  
                    const integer i = iter->index;
191  
                    x_coord[i] = iter->pt[0];
192  
                    y_coord[i] = iter->pt[1];
193  
                    z_coord[i] = iter->pt[2];
194  
                }
195  
196  
                constexpr
197  
                int nshapes = 1;
198  
                int shapesize[1] = {NVERTEX};
199  
                int shapetype[1] = {DB_ZONETYPE_HEX};
200  
                int shapecnt[1] = {nzones};
201  
                const char* coord_names[NDIM] = {"x", "y", "z"};
202  
203  
#ifndef	__MIC__
204  
                auto olist = DBMakeOptlist(1);
205  
                double time = double(t);
206  
                int ndim = 3;
207  
                DBAddOption(olist, DBOPT_CYCLE, &cycle);
208  
                DBAddOption(olist, DBOPT_DTIME, &time);
209  
                DBAddOption(olist, DBOPT_NSPACE, &ndim );
210  
                DBfile *db = DBCreateReal(filename.c_str(), DB_CLOBBER, DB_LOCAL, "Euler Mesh", DB_PDB);
211  
                assert(db);
212  
                DBPutZonelist2(db, "zones", nzones, int(NDIM), zone_nodes.data(), nzones * NVERTEX, 0, 0, 0, shapetype, shapesize,
213  
                        shapecnt, nshapes, olist);
214  
                DBPutUcdmesh(db, "mesh", int(NDIM), const_cast<char**>(coord_names), node_coords.data(), nnodes, nzones, "zones", nullptr, DB_DOUBLE,
215  
                        olist);
216  
                const char* analytic_names[] = {"rho_a", "egas_a", "sx_a", "sy_a", "sz_a", "tau_a"};
217  
                DBFreeOptlist(olist);
218  
                for (int field = 0; field != NF + NGF + NPF; ++field) {
219  
                    auto olist = DBMakeOptlist(1);
220  
                    double time = double(t);
221  
                    int istrue = 1;
222  
                    int isfalse = 0;
223  
                    DBAddOption(olist, DBOPT_CYCLE, &cycle);
224  
                    DBAddOption(olist, DBOPT_DTIME, &time);
225  
                    DBAddOption(olist, DBOPT_NSPACE, &ndim );
226  
                    if( field == rho_i || field == sx_i || field == sy_i || field == sz_i || field == spc_ac_i || field == spc_ae_i || field == spc_dc_i || field == spc_de_i || field == spc_vac_i ) {
227  
                        DBAddOption(olist, DBOPT_CONSERVED, &istrue);
228  
                    } else {
229  
                        DBAddOption(olist, DBOPT_CONSERVED, &isfalse );
230  
                    }
231  
                    if( field < NF ) {
232  
                        DBAddOption(olist, DBOPT_EXTENSIVE, &istrue);
233  
                    } else {
234  
                        DBAddOption(olist, DBOPT_EXTENSIVE, &isfalse);
235  
                    }
236  
                    DBAddOption(olist, DBOPT_EXTENSIVE, &istrue);
237  
                    DBPutUcdvar1(db, field_names[field], "mesh", const_cast<void*>(reinterpret_cast<const void*>(olists.data[field].data())), nzones, nullptr, 0, DB_DOUBLE, DB_ZONECENT,
238  
                            olist);
239  
                    if( analytic && field < 6) {
240  
                        DBPutUcdvar1(db, analytic_names[field], "mesh", const_cast<void*>(reinterpret_cast<const void*>(olists.analytic[field].data())), nzones, nullptr, 0, DB_DOUBLE, DB_ZONECENT,
241  
                                olist);
242  
                    }
243  
                    DBFreeOptlist(olist);
244  
#ifdef RHO_ONLY
245  
                    break;
246  
#endif
247  
                }
248  
                DBClose(db);
249  
#endif
250  
            }, _filename, _t).join();
251  
#endif
252  
}
253  
254  
std::size_t grid::load(FILE* fp) {
255  
    std::size_t cnt = 0;
256  
    auto foo = std::fread;
257  
    {
258  
        static hpx::mutex mtx;
259  
        std::lock_guard<hpx::mutex> lock(mtx);
260  
        cnt += foo(&scaling_factor, sizeof(real), 1, fp) * sizeof(real);
261  
        cnt += foo(&max_level, sizeof(integer), 1, fp) * sizeof(integer);
262  
        cnt += foo(&Acons, sizeof(real), 1, fp) * sizeof(real);
263  
        cnt += foo(&Bcons, sizeof(integer), 1, fp) * sizeof(integer);
264  
    }
265  
    cnt += foo(&is_leaf, sizeof(bool), 1, fp) * sizeof(bool);
266  
    cnt += foo(&is_root, sizeof(bool), 1, fp) * sizeof(bool);
267  
268  
    allocate();
269  
270  
    for (integer f = 0; f != NF; ++f) {
271  
        for (integer i = H_BW; i < H_NX - H_BW; ++i) {
272  
            for (integer j = H_BW; j < H_NX - H_BW; ++j) {
273  
                const integer iii = hindex(i, j, H_BW);
274  
                cnt += foo(&(U[f][iii]), sizeof(real), INX, fp) * sizeof(real);
275  
            }
276  
        }
277  
    }
278  
    for (integer i = 0; i < G_NX; ++i) {
279  
        for (integer j = 0; j < G_NX; ++j) {
280  
            for (integer k = 0; k < G_NX; ++k) {
281  
                const integer iii = gindex(i, j, k);
282  
                real g[NGF];
283  
            	cnt += foo(g, sizeof(real), NGF, fp) * sizeof(real);
284  
                for( integer f = 0; f != NGF; ++f) {
285  
                	G[iii][f] = g[f];
286  
                }
287  
            }
288  
        }
289  
    }
290  
    cnt += foo(U_out.data(), sizeof(real), U_out.size(), fp) * sizeof(real);
291  
    set_coordinates();
292  
    return cnt;
293  
}
294  
295  
std::size_t grid::save(FILE* fp) const {
296  
    std::size_t cnt = 0;
297  
    auto foo = std::fwrite;
298  
    {
299  
        static hpx::mutex mtx;
300  
        std::lock_guard<hpx::mutex> lock(mtx);
301  
        cnt += foo(&scaling_factor, sizeof(real), 1, fp) * sizeof(real);
302  
        cnt += foo(&max_level, sizeof(integer), 1, fp) * sizeof(integer);
303  
        cnt += foo(&Acons, sizeof(real), 1, fp) * sizeof(real);
304  
        cnt += foo(&Bcons, sizeof(integer), 1, fp) * sizeof(integer);
305  
    }
306  
    cnt += foo(&is_leaf, sizeof(bool), 1, fp) * sizeof(bool);
307  
    cnt += foo(&is_root, sizeof(bool), 1, fp) * sizeof(bool);
308  
    for (integer f = 0; f != NF; ++f) {
309  
        for (integer i = H_BW; i < H_NX - H_BW; ++i) {
310  
            for (integer j = H_BW; j < H_NX - H_BW; ++j) {
311  
                const integer iii = hindex(i, j, H_BW);
312  
                cnt += foo(&U[f][iii], sizeof(real), INX, fp) * sizeof(real);
313  
            }
314  
        }
315  
    }
316  
    for (integer i = 0; i < G_NX; ++i) {
317  
        for (integer j = 0; j < G_NX; ++j) {
318  
            for (integer k = 0; k < G_NX; ++k) {
319  
                const integer iii = gindex(i, j, k);
320  
                const auto d = G[iii][0];
321  
                cnt += foo(&d, sizeof(real), NGF, fp) * sizeof(real);
322  
            }
323  
        }
324  
    }
325  
    cnt += foo(U_out.data(), sizeof(real), U_out.size(), fp) * sizeof(real);
326  
    return cnt;
327  
}
328  
329  

Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.