Line data Source code
1 : //
2 : // Initialize a field using a PNG image. (2D only)
3 : //
4 :
5 : #ifndef IC_PNG_H
6 : #define IC_PNG_H
7 : #include <cmath>
8 :
9 : #ifndef ALAMO_NOPNG
10 : #include <stdarg.h>
11 : #include <stddef.h>
12 : #include <setjmp.h>
13 : #include <png.h>
14 : #endif
15 :
16 : #include "IC/IC.H"
17 : #include "Util/Util.H"
18 : #include "Util/BMP.H"
19 : #include "Set/Set.H"
20 : #include "IO/ParmParse.H"
21 : #include "Util/PNG.H"
22 :
23 : namespace IC
24 : {
25 : class PNG : public IC<Set::Scalar>
26 : {
27 : public:
28 : static constexpr const char* name = "png";
29 :
30 : //enum Type {XYZ, XY, YZ, XZ};
31 : enum Fit { Stretch, FitWidth, FitHeight, Coord };
32 : enum Channel { R = 0, G = 1, B = 2, A = 3 };
33 :
34 0 : virtual ~PNG() {}
35 :
36 0 : PNG(amrex::Vector<amrex::Geometry>& _geom) : IC(_geom) {}
37 :
38 0 : PNG(amrex::Vector<amrex::Geometry>& _geom, IO::ParmParse& pp, std::string name) : PNG(_geom)
39 : {
40 0 : pp_queryclass(name, *this);
41 0 : }
42 :
43 0 : PNG(amrex::Vector<amrex::Geometry>& _geom, Unit a_unit, IO::ParmParse& pp, std::string name) : PNG(_geom)
44 : {
45 0 : unit = a_unit;
46 0 : pp_queryclass(name, *this);
47 0 : }
48 :
49 0 : void Add(const int& lev, Set::Field<Set::Scalar>& a_field, Set::Scalar)
50 : {
51 :
52 : #ifndef ALAMO_NOPNG
53 0 : Set::Vector DX(geom[lev].CellSize());
54 0 : amrex::Box domain = geom[lev].Domain();
55 :
56 0 : amrex::IndexType type = a_field[lev]->ixType();
57 0 : domain.convert(type);
58 :
59 0 : Set::Vector domlo(AMREX_D_DECL(geom[lev].ProbLo()[0], geom[lev].ProbLo()[1], 0.0));
60 0 : Set::Vector domhi(AMREX_D_DECL(geom[lev].ProbHi()[0], geom[lev].ProbHi()[1], 0.0));
61 :
62 0 : png.setDomain(domlo, domhi);
63 :
64 0 : for (amrex::MFIter mfi(*a_field[lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
65 : {
66 0 : amrex::Box bx;
67 0 : if (type == amrex::IndexType::TheNodeType()) bx = mfi.grownnodaltilebox();
68 0 : if (type == amrex::IndexType::TheCellType()) bx = mfi.growntilebox();
69 0 : bx = bx & domain;
70 :
71 0 : amrex::Array4<Set::Scalar> const& field = a_field[lev]->array(mfi);
72 0 : amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k)
73 : {
74 0 : Set::Vector x = Set::Vector::Zero();
75 : // NODE
76 0 : if (type == amrex::IndexType::TheNodeType())
77 : {
78 0 : x(0) = domlo(0) + ((amrex::Real)(i)) * geom[lev].CellSize()[0];
79 0 : x(1) = domlo(1) + ((amrex::Real)(j)) * geom[lev].CellSize()[1];
80 : }
81 0 : else if (type == amrex::IndexType::TheCellType())
82 : {
83 0 : x(0) = domlo(0) + ((amrex::Real)(i)+0.5) * geom[lev].CellSize()[0];
84 0 : x(1) = domlo(1) + ((amrex::Real)(j)+0.5) * geom[lev].CellSize()[1];
85 : }
86 :
87 :
88 0 : std::array<Set::Scalar, 4> val = png(x);
89 :
90 0 : field(i,j,k,0) = val[channel] * unit.normalized_value();
91 :
92 0 : if (field.nComp() > 1) field(i, j, k, 1) = 1.0 - field(i, j, k, 0);
93 :
94 0 : });
95 0 : }
96 0 : a_field[lev]->FillBoundary();
97 : #else
98 : Util::IgnoreUnused(lev,a_field);
99 : Util::Abort(INFO,"PNG is disabled");
100 : #endif
101 :
102 0 : };
103 :
104 : private:
105 : #ifndef ALAMO_NOPNG
106 : Util::PNG png;
107 : Channel channel = Channel::G;
108 : Unit unit = Unit::Less();
109 : #endif
110 :
111 : public:
112 0 : static void Parse(PNG& value, IO::ParmParse& pp)
113 : {
114 : #ifndef ALAMO_NOPNG
115 :
116 0 : std::string channel = "g";
117 : // Color channel to use (options: r, R, g, G, b, B, a, A)
118 0 : pp_query_validate("channel", channel, {"r","g","b","a","R","G","B","A"});
119 0 : if (channel == "r" || channel == "R") value.channel = Channel::R;
120 0 : else if (channel == "g" || channel == "G") value.channel = Channel::G;
121 0 : else if (channel == "b" || channel == "B") value.channel = Channel::B;
122 0 : else if (channel == "a" || channel == "A") value.channel = Channel::A;
123 0 : else Util::Abort(INFO, "Invalid value for bmp channel - should be r/g/b/a but received '", channel, "'");
124 :
125 :
126 0 : pp.queryclass<Util::PNG>(value.png);
127 :
128 : #else
129 : Util::Abort(INFO,"PNG is disabled");
130 : #endif
131 0 : }
132 : };
133 : }
134 : #endif
|