26template <
typename gr
id_type,
int SDF,
int normal>
28 const std::array<double,grid_type::dims> & center,
29 const double radius) {
34 double dist, arg, theta, phi;
35 std::array<double, grid_type::dims> coord;
37 auto it =
grid.getDomainIterator();
43 coord[d] =
grid.getPos(key)[d];
44 dist += (coord[d]-center[d])*(coord[d]-center[d]);
46 arg = (coord[x]-center[x]) * (coord[x]-center[x]) + (coord[y]-center[y]) * (coord[y]-center[y]);
47 theta = std::atan2(std::sqrt(arg),(coord[z]-center[z]));
48 phi = std::atan2((coord[y]-center[y]),(coord[x]-center[x]));
50 grid.template get<SDF>(key) = std::sqrt(dist) - radius;
51 grid.template get<normal>(key)[x] = std::sin(theta)*std::cos(phi);
52 grid.template get<normal>(key)[y] = std::sin(theta)*std::sin(phi);
53 grid.template get<normal>(key)[z] = std::cos(theta);
60template <
typename gr
id_type,
int SDF>
62 const std::array<double,grid_type::dims> & center,
63 const double radius) {
66 std::array<double, grid_type::dims> coord;
68 auto it =
grid.getDomainIterator();
74 coord[d] =
grid.getPos(key)[d];
75 dist += (coord[d]-center[d])*(coord[d]-center[d]);
78 grid.template get<SDF>(key) = std::sqrt(dist) - radius;
85template <
typename gr
id_type,
int qty,
typename key_type>
87 const std::array<double,grid_type::dims> & center,
88 std::vector<key_type> & nb_keys) {
93 double arg, theta, cos2;
94 const double pi{3.14159265358979323846};
95 const double prefactor{3.0/16.0 * std::sqrt(1.0/pi)};
96 std::array<double,
grid.dims> coord;
98 for (
int i = 0; i < nb_keys.size(); ++i) {
100 for (
int d = 0; d <
grid.dims; ++d)
101 coord[d] =
grid.getPos(nb_keys[i])[d];
103 arg = (coord[x]-center[x]) * (coord[x]-center[x]) + (coord[y]-center[y]) * (coord[y]-center[y]);
104 theta = std::atan2(std::sqrt(arg),(coord[z]-center[z]));
105 cos2 = std::cos(theta)*std::cos(theta);
107 grid.template get<qty>(nb_keys[i]) = prefactor * (cos2*(35.0*cos2 - 30.0) + 3.0);
114template <
typename gr
id_type,
int qty>
116 const std::array<double,grid_type::dims> & center) {
121 double arg, theta, cos2;
122 const double pi{3.14159265358979323846};
123 const double prefactor{3.0/16.0 * std::sqrt(1.0/pi)};
124 std::array<double,
grid.dims> coord;
126 auto it =
grid.getDomainIterator();
130 for (
int d = 0; d <
grid.dims; ++d)
131 coord[d] =
grid.getPos(key)[d];
133 arg = (coord[x]-center[x]) * (coord[x]-center[x]) + (coord[y]-center[y]) * (coord[y]-center[y]);
134 theta = std::atan2(std::sqrt(arg),(coord[z]-center[z]));
135 cos2 = std::cos(theta)*std::cos(theta);
137 grid.template get<qty>(key) = prefactor * (cos2*(35.0*cos2 - 30.0) + 3.0);
142template <
typename gr
id_type,
int qty,
int sol>
144 const std::array<double,grid_type::dims> & center,
145 const double radius) {
150 double arg, theta, cos2;
151 const double pi{3.14159265358979323846};
152 const double prefactor{3.0/16.0 * std::sqrt(1.0/pi)};
153 std::array<double,
grid.dims> coord;
155 auto it =
grid.getDomainIterator();
159 for (
int d = 0; d <
grid.dims; ++d)
160 coord[d] =
grid.getPos(key)[d];
162 arg = (coord[x]-center[x]) * (coord[x]-center[x]) + (coord[y]-center[y]) * (coord[y]-center[y]);
163 theta = std::atan2(std::sqrt(arg),(coord[z]-center[z]));
164 cos2 = std::cos(theta)*std::cos(theta);
166 grid.template get<sol>(key) = -20.0 * prefactor * (cos2*(35.0*cos2 - 30.0) + 3.0);
172bool within_narrow_band(
double phi,
175 return (phi >= b_low && phi <= b_up);
178template<
typename gr
id_type,
size_t prop,
typename key_type>
181 std::vector<key_type> & nb_keys) {
183 double b_low = -thickness/2.0;
184 double b_up = thickness/2.0;
186 auto it{
grid.getDomainIterator()};
187 while (it.isNext()) {
190 if (within_narrow_band(
grid.template get<prop>(key),b_low,b_up))
191 nb_keys.push_back(key);
202template<
typename gr
id_type,
int PropNumeric,
int PropAnalytic,
int Error,
typename key_type>
204 std::vector<key_type> & nb_keys) {
205 for (
int i = 0; i < nb_keys.size(); ++i)
206 grid.template getProp<Error>(nb_keys[i]) = std::fabs(
grid.template getProp<PropAnalytic>(nb_keys[i]) - (
grid.template getProp<PropNumeric>(nb_keys[i])));
209template<
typename gr
id_type,
int error,
typename key_type>
211 std::vector<key_type> & nb_keys) {
214 double sumErrorSq{0};
215 size_t num_nb{nb_keys.size()};
217 for (
int i = 0; i < nb_keys.size(); ++i) {
219 sumErrorSq +=
grid.template getProp<error>(nb_keys[i]) *
grid.template getProp<error>(nb_keys[i]);
220 if (
grid.template getProp<error>(nb_keys[i]) > maxError)
221 maxError =
grid.template getProp<error>(nb_keys[i]);
225 auto &v_cl = create_vcluster();
227 v_cl.sum(sumErrorSq);
231 double l2{std::sqrt(sumErrorSq / (
double)num_nb)};
233 double linf{maxError};
238void write_lnorms_to_file(T N,
L_norms l_norms, std::string filename, std::string path_output) {
239 auto &v_cl = create_vcluster();
240 if (v_cl.rank() == 0) {
241 std::string path_output_lnorm{path_output +
"/" + filename +
".csv"};
245 l_out.open(path_output_lnorm, std::ios::app);
246 l_out << N <<
',' << std::setprecision(6) << std::scientific << l_norms.l2 <<
',' << l_norms.linf
253template<
typename vector_type,
int prop>
257 while (it.isNext()) {
259 vec.template getProp<prop>(key) = 0.0;
void get_absolute_error(gridtype &grid)
At each grid node, the absolute error is computed and stored in another property.
static void create_file_if_not_exist(std::string path)
Creates a file if not already existent.
This is a distributed grid.
static const unsigned int dims
Number of dimensions.
vect_dist_key_dx get()
Get the actual key.
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.