15#ifndef Coarsen_Operator_K_TPP_H
16#define Coarsen_Operator_K_TPP_H
18#include <Domaine_IJK.h>
20#include <communications.h>
22#include <Perf_counters.h>
24template<
typename _TYPE_>
27 int additional_k_layers)
37 const Domaine_IJK& src_grid_geom = fine.
get_domaine();
42 const int n_coord_fine = coord_z_fine.
size_array();
43 const int n_coord_coarse = coord_z_coarse.
size_array();
44 if (std::fabs(coord_z_fine[0] - coord_z_coarse[0]) > epsilon
45 || std::fabs(coord_z_fine[n_coord_fine-1] - coord_z_coarse[n_coord_coarse-1]) > epsilon)
47 Cerr <<
"Error in Coarsen_Operator_K::initialize_grid_data: coarse and fine grids have wrong size" << finl;
48 Cerr <<
" fine grid: " << coord_z_fine[0] <<
" .. " << coord_z_fine[n_coord_fine-1] << finl;
49 Cerr <<
" coarse grid: " << coord_z_coarse[0] <<
" .. " << coord_z_coarse[n_coord_coarse-1] << finl;
53 ArrOfDouble coarse_delta_k(n_coord_coarse - 1);
55 for (
int i = 0; i < n_coord_coarse - 1; i++)
56 coarse_delta_k[i] = coord_z_coarse[i+1] - coord_z_coarse[i];
58 int current_coarse_cell = 0;
59 int current_fine_cell = 0;
60 Journal() <<
"Coarsen_Operator_K: global coarsening coefficients:\nfine_k coarse_k coarsen_coeff avg_coeff:" << endl;
67 double fine_cell_size = coord_z_fine[current_fine_cell+1] - coord_z_fine[current_fine_cell];
68 double coarse_cell_size = coarse_delta_k[current_coarse_cell];
69 const double zmin = std::max(coord_z_fine[current_fine_cell], coord_z_coarse[current_coarse_cell]);
70 const double zmax = std::min(coord_z_fine[current_fine_cell+1], coord_z_coarse[current_coarse_cell+1]);
71 double intersection = zmax - zmin;
72 if (fine_cell_size <= 0. || coarse_cell_size <= 0. || intersection <= 0.)
74 Cerr <<
"Error in Coarsen_Operator_K::initialize_grid_data: wrong cell sizes" << finl
75 <<
" fine cell " << current_fine_cell <<
" zmin=" << coord_z_fine[current_fine_cell] ;
76 Cerr <<
" zmax=" << coord_z_fine[current_fine_cell+1] << finl;
77 Cerr <<
" coarse cell " << current_coarse_cell <<
" zmin=" << coord_z_coarse[current_coarse_cell]
78 <<
" zmax=" << coord_z_coarse[current_coarse_cell+1] << finl;
84 Journal() << current_fine_cell <<
" " << current_coarse_cell <<
" "
88 if (std::fabs(coord_z_fine[current_fine_cell + 1] - coord_z_coarse[current_coarse_cell+1]) < epsilon)
92 current_coarse_cell++;
94 else if (coord_z_fine[current_fine_cell + 1] < coord_z_coarse[current_coarse_cell+1])
102 current_coarse_cell++;
105 if (current_coarse_cell == n_coord_coarse-1)
107 assert(current_fine_cell == n_coord_fine-1);
110 assert(current_fine_cell < n_coord_fine - 1);
113 Domaine_IJK grid_geom;
128 Domaine_IJK coarse_splitting;
130 IntTab processor_mapping;
133 ArrOfInt slice_size_i, slice_size_j, fine_slice_size_k, coarse_slice_size_k;
142 int end_of_fine_slice = fine_slice_size_k[0];
143 int previous_coarse_cell = -1;
152 if (previous_coarse_cell == next_coarse_cell)
156 Cerr <<
"Error in Coarsen_Operator_K::initialize_grid_data: "
157 <<
" cannot merge cells across processors, you must put a coarse node at z=";
158 Cerr << coord_z_fine[
src_dest_index_(i,0)] <<
" (or modify processor splitting)" << finl;
162 end_of_fine_slice += fine_slice_size_k[slice_num];
164 if (previous_coarse_cell != next_coarse_cell)
165 coarse_slice_size_k[slice_num]++;
166 previous_coarse_cell = next_coarse_cell;
173 coarse_splitting.
initialize_mapping(grid_geom, slice_size_i, slice_size_j, coarse_slice_size_k, processor_mapping);
175 coarse.
initialize(coarse_splitting, ghost_domaine_size, additional_k_layers);
187 const int fine_start = fine_k_offset;
190 const int coarse_start = coarse_k_offset;
194 Journal() <<
"Coarsen_Operator_K: local coarsening coefficients:\nfine_k coarse_k coarsen_coeff avg_coeff:" << endl;
195 for (
int i = 0; i < n; i++)
201 if ((fine_k >= fine_start && fine_k < fine_start + fine_nlocal)
202 || (coarse_k >= coarse_start && coarse_k < coarse_start + coarse_nlocal))
210 Journal() << fine_k - fine_k_offset <<
" " << coarse_k - coarse_k_offset <<
" "
217template <
typename _TYPE_,
typename _TYPE_ARRAY_>
220 int compute_weighted_average)
const
223 statistics().
begin_count(
"multigrid: K coarsening",statistics().get_last_opened_counter_level()+1);
225 const int index_start = 0;
227 const int delta_index = 1;
229 const int ni = coarse.
ni();
230 const int nj = coarse.
nj();
234 int previous_coarse_k = -10;
236 for (
int index = index_start; index != index_end; index += delta_index)
242 const _TYPE_ coef = (_TYPE_)coef_array[index];
243 if (coarse_k != previous_coarse_k)
246 for (
int j = 0; j < nj; j++)
247 for (
int i = 0; i < ni; i++)
248 coarse(i, j, coarse_k) = coef * fine(i, j, fine_k);
249 previous_coarse_k = coarse_k;
254 for (
int j = 0; j < nj; j++)
255 for (
int i = 0; i < ni; i++)
256 coarse(i, j, coarse_k) += coef * fine(i, j, fine_k);
259 statistics().
end_count(
"multigrid: K coarsening");
262template <
typename _TYPE_,
typename _TYPE_ARRAY_>
265 const int kshift)
const
268 statistics().
begin_count(
"multigrid: interpolate K",statistics().get_last_opened_counter_level()+1);
271 const int delta_index = kshift <= 0 ? 1 : -1;
273 const int ni = coarse.
ni();
274 const int nj = coarse.
nj();
277 int previous_fine_k = -10;
279 for (
int index = index_start; index != index_end; index += delta_index)
283 const _TYPE_ coef = (_TYPE_)coef_array[index];
284 if (fine_k != previous_fine_k)
286 previous_fine_k = fine_k;
288 for (
int J = 0; J < nj; J++)
289 for (
int I = 0; I < ni; I++)
295 for (
int J = 0; J < nj; J++)
296 for (
int I = 0; I < ni; I++)
302 statistics().
end_count(
"multigrid: interpolate K");
ArrOfDouble coarsen_coefficients_local_
ArrOfDouble avg_coefficients_
ArrOfDouble avg_coefficients_local_
IntTab src_dest_index_local_
ArrOfDouble coarsen_coefficients_
int get_offset_local(int direction) const
Returns the local offset in requested direction.
int get_nb_elem_local(int direction) const
Returns the number of elements owned by this processor in the given direction.
bool get_periodic_flag(int direction) const
Method returns true if periodic in this direction.
void get_processor_mapping(IntTab &mapping) const
Fills an array containing the mapping of processors.
const ArrOfDouble & get_delta(int direction) const
Returns the array of mesh cell sizes in requested direction.
double get_origin(int direction) const
Returns the coordinate of the first node (global) of the mesh in the requested direction.
void initialize_mapping(Domaine_IJK &dom, const ArrOfInt &slice_size_i, const ArrOfInt &slice_size_j, const ArrOfInt &slice_size_k, const IntTab &processor_mapping)
Creates a splitting of the domain by specifying the slice sizes and the processor mapping.
void get_slice_size(int direction, Localisation loc, ArrOfInt &tab) const
Returns the number of items of given location (elements, nodes, faces...) for all slices in the reque...
const ArrOfDouble & get_node_coordinates(int direction) const
Returns an array with the coordinates of all nodes in the mesh in requested direction.
void initialize_origin_deltas(double x0, double y0, double z0, const ArrOfDouble &delta_x, const ArrOfDouble &delta_y, const ArrOfDouble &delta_z, bool perio_x, bool perio_y, bool perio_z)
Initializes class elements given dataset's parameters.
int get_ghost_size() const
void initialize(const Domaine_IJK &, int ghost, int additional_k_layers)
const Domaine_IJK & get_domaine() const
_TYPE_ & get_in_allocated_area(int i, int j, int k)
void shift_k_origin(int n)
: This class is an IJK_Field_local with parallel informations.
static double precision_geom
void begin_count(const STD_COUNTERS &std_cnt, int counter_lvl=-100000)
void end_count(const std::string &custom_count_name, int count_increment=1, long int quantity_increment=0)
End the count of a counter and update the counter values.
void create_custom_counter(std::string counter_description, int counter_level, std::string counter_family="None", bool is_comm=false, bool is_gpu=false)
Create a new counter and add it to the map of custom counters.
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)