14 #include "eckit/exception/Exceptions.h"
15 #include "eckit/log/Log.h"
19 using namespace eckit;
25 #define regions(i, j, k) regs[((k)-1) * dim * 2 + ((j)-1) * dim + (i)-1]
26 #define regions_1(i, j, k) regs_1[((k)-1) * (dim - 1) * 2 + ((j)-1) * (dim - 1) + (i)-1]
27 #define region(i, j) reg[((j)-1) * dim + (i)-1]
29 extern double mfmod(
double x,
double y);
45 return (
m == 0) ? n :
gcd(n %
m,
m);
67 Log::info() <<
"bot_cap_region: dim > 2 not supported";
88 double co = (double)(1 / (
double)(n_bot)-1 / (
double)(n_top)) / 2 +
89 (double)(
gcd(n_top, n_bot)) / (2 * (
double)(n_top) * (
double)(n_bot));
95 const int n_regions[],
double c_caps[])
109 int subtotal_n_regions, collar_n;
112 subtotal_n_regions = 1;
114 for (collar_n = 1; collar_n <= n_collars; collar_n++) {
115 subtotal_n_regions += n_regions[collar_n];
116 area = subtotal_n_regions * ideal_region_area;
138 double discrepancy = 0;
139 for (j = 0; j < n_collars + 2; j++) {
140 n_regions[j] =
NINT(r_regions[j] + discrepancy);
141 discrepancy += r_regions[j] - n_regions[j];
168 Log::info() <<
"area_of_cap: dim > 2 not supported";
220 double a_fitting = (
piconst::pi - 2 * c_polar) / n_collars;
222 for (collar_n = 1; collar_n <= n_collars; collar_n++) {
223 double ideal_collar_area =
224 area_of_collar(
dim, c_polar + (collar_n - 1) * a_fitting, c_polar + collar_n * a_fitting);
225 r_regions[collar_n] = ideal_collar_area / ideal_region_area;
228 r_regions[n_collars + 1] = 1;
259 bool enough = ((n > 2) && (a_ideal > 0)) ?
true :
false;
294 const double p0 = 0.999999999999999990e0;
295 const double p1 = -0.422784335098466784e0;
296 const double p2 = -0.233093736421782878e0;
297 const double p3 = 0.191091101387638410e0;
298 const double p4 = -0.024552490005641278e0;
299 const double p5 = -0.017645244547851414e0;
300 const double p6 = 0.008023273027855346e0;
301 const double p7 = -0.000804329819255744e0;
302 const double p8 = -0.000360837876648255e0;
303 const double p9 = 0.000145596568617526e0;
304 const double p10 = -0.000017545539395205e0;
305 const double p11 = -0.000002591225267689e0;
306 const double p12 = 0.000001337767384067e0;
307 const double p13 = -0.000000199542863674e0;
309 double w = x - (n + 2);
311 ((((((((((((p13 * w + p12) * w + p11) * w + p10) * w + p9) * w + p8) * w + p7) * w + p6) * w + p5) * w + p4) *
323 for (k = 2; k <= n; k++)
329 for (k = 0; k <= nn; k++)
341 double power = (double)(
dim + 1) / (double)2;
360 Log::info() <<
"sradius_of_cap: dim > 2 not supported";
405 Log::info() <<
"top_cap_region: dim > 2 not supported";
431 Log::info() <<
"sphere_region: dim > 2 not supported";
441 int n_collars = *N_collars;
465 for (j = 0; j < n; j++) {
501 double* r_regions = NULL;
502 r_regions =
new double[n_collars + 2];
556 double* regs_1 = NULL;
557 double *s_cap = NULL, r_top[2], r_bot[2], c_top, c_bot, offset;
558 int *n_regions = NULL, collar_n, n_collars, n_in_collar, region_1_n, region_n;
561 s_cap =
new double[n + 2];
562 n_regions =
new int[n + 2];
583 eq_caps(
dim, n, s_cap, n_regions, &n_collars);
599 for (k = 1; k <= n; k++)
600 for (j = 1; j <= 2; j++)
601 for (
i = 1;
i <=
dim;
i++)
604 for (k = 2; k <= n; k++)
605 regions(1, 1, k) = s_cap[k - 2];
607 for (k = 1; k <= n; k++)
608 regions(1, 2, k) = s_cap[k - 1];
633 for (collar_n = 1; collar_n <= n_collars; collar_n++) {
634 int size_regions_1_3;
638 c_top = s_cap[collar_n - 1];
643 c_bot = s_cap[collar_n];
648 n_in_collar = n_regions[collar_n];
658 size_regions_1_3 = n_in_collar;
660 regs_1 =
new double[(
dim - 1) * 2 * (n - 1)];
672 for (region_1_n = 1; region_1_n <= n_in_collar; region_1_n++) {
695 if (r_bot[0] <= r_top[0])
700 regions(1, 1, region_n) = r_top[0];
701 regions(1, 2, region_n) = r_bot[0];
702 regions(2, 1, region_n) = r_top[1];
703 regions(2, 2, region_n) = r_bot[1];
711 offset +=
circle_offset(n_in_collar, n_regions[1 + collar_n]);
712 offset -= floor(offset);
715 for (region_1_n = 1; region_1_n <= size_regions_1_3; region_1_n++) {
723 for (j = 1; j <= 2; j++)
724 for (
i = 1;
i <=
dim - 1;
i++)
781 double eq_area_value =
eq_area(rn);
795 int nbelm =
dim * 2 * resol;
797 regs =
new double[nbelm];
808 for (j = 1; j <= n; j++) {
810 double startlon =
regions(1, 1, j);
811 double startlat =
regions(2, 1, j);
812 double endlon =
regions(1, 2, j);
813 double endlat =
regions(2, 2, j);
818 if (j == 1 || j == n) {
837 double three_sixty = 360;
838 double last_startlat =
regions(2, 1, j);
839 double last_endlat =
regions(2, 2, j);
842 for (j = 2; j < n; j++) {
843 double startlat =
regions(2, 1, j);
844 double endlat =
regions(2, 2, j);
845 if (last_startlat == startlat && last_endlat == endlat) {
852 last_startlat = startlat;
853 last_endlat = endlat;
865 double* latband =
new double[nb + 1];
866 int* loncnt =
new int[nb];
867 double* stlon =
new double[nb];
868 double* deltalon =
new double[nb];
873 last_startlat =
regions(2, 1, j);
874 last_endlat =
regions(2, 2, j);
876 latband[jb] = -
R2D(last_startlat);
878 for (j = 2; j < n; j++) {
879 double startlat =
regions(2, 1, j);
880 double endlat =
regions(2, 2, j);
881 if (last_startlat == startlat && last_endlat == endlat) {
888 deltalon[jb] = three_sixty / ncnt;
889 stlon[jb] = -deltalon[jb] / 2;
891 last_startlat = startlat;
892 last_endlat = endlat;
894 latband[jb] = -
R2D(last_startlat);
900 deltalon[jb] = three_sixty / ncnt;
901 stlon[jb] = -deltalon[jb] / 2;
903 last_startlat =
regions(2, 1, j);
904 last_endlat =
regions(2, 2, j);
906 latband[jb] = -
R2D(last_startlat);
911 deltalon[jb] = three_sixty / ncnt;
912 stlon[jb] = -deltalon[jb] / 2;
914 latband[++jb] = -
R2D(last_endlat);
923 double* midlat =
new double[nb];
924 for (jb = 0; jb < nb; jb++) {
925 midlat[jb] = (latband[jb] + latband[jb + 1]) / 2;
#define regions_1(i, j, k)
double eq_area(const double &)
double eq_resol(const double &)
void bot_cap_region(int &, double &, double[])
virtual double get_resol(const double &val)
double polar_colat(int &, int &)
double area_of_sphere(int &)
double my_gamma(double &)
void ideal_region_list(int &, int &, double &, int &, double[])
void sphere_region(int &, double[])
int num_collars(int &, double &, double)
void top_cap_region(int &, double &, double[])
void cap_colats(int &, int &, int &, double &, const int[], double[])
double area_of_ideal_region(int &, int &)
double sradius_of_cap(int &, double &)
double eq_n(const double &)
void eq_caps(int &, int &, double[], int[], int *)
void eq_regions(int, int, double[])
void round_to_naturals(int &, int &, const double[], int[])
double area_of_collar(int &, double, double)
virtual void create_cache(const double &, const int &)
double area_of_cap(int &, double &)
double ideal_collar_angle(int &, int &)
double circle_offset(int &, int &)
void put_cache(const RegionCacheKind &kind, const double &, const int &, double[], double[], double[], double[], int[])
real(8), parameter radius
constexpr double pi_over_180
constexpr double recip_pi_over_180
double mfmod(double x, double y)
static const double min_resol
static const double sphere_area