10 #include "statistics.h"
18 #define snprintf _snprintf
22 using namespace linal;
24 static inline double max (double a, double b)
26 return (a > b) ? a : b;
29 double ans (double x, double y, double t)
31 return x*sin (y + t) *ipow (cos (x), 4);
34 double zero_coriolis (double phi, double lambda, double t, const SphereBarvortex::Conf * conf)
39 double f (double x, double y, double t, const SphereBarvortex::Conf * conf)
42 double sigma = conf->sigma;
43 return 390*mu*sin(y+t)*x*ipow(cos(x),2)
44 +147*mu*sin(y+t)*sin(x)*cos(x)-
46 ipow(cos(x),4)-360*mu*sin(y+t)*
47 sin(x)*ipow(cos(x),3)-20*sigma*sin(y+t)*
48 ipow(cos(x),4)*x+15*sigma*sin(y+t)*
49 ipow(cos(x),2)*x-9*sigma*sin(y+t)*
50 ipow(cos(x),3)*sin(x)+30*cos(y+t)*
51 ipow(cos(x),4)*sin(y+t)*x*x*sin(x)+9*cos(y+t)*
52 ipow(cos(x),6)*sin(y+t)*sin(x)-45*mu*sin(y+t)*x-
53 9*cos(y+t)*ipow(cos(x),5)*sin(y+t)*x-20*x*cos(y+t)*
54 ipow(cos(x),4)-9*cos(y+t)*
55 ipow(cos(x),3)*sin(x)+15*x*cos(y+t)*
64 SphereBarvortex::Conf conf;
74 conf.cor = zero_coriolis;
76 double dlat = M_PI / (nlat - 1);
77 double dlon = 2. * M_PI / nlon;
82 vector < double > u (nlat * nlon);
83 vector < double > v (nlat * nlon);
84 vector < double > r (nlat * nlon);
86 SphereBarvortex bv (conf);
90 for (i = 0; i < nlat; ++i)
92 for (j = 0; j < nlon; ++j)
94 double phi = -0.5 * M_PI + i * dlat;
95 double lambda = j * dlon;
97 r[i * nlon + j] = ans (phi, lambda, t);
103 bv.S_step (&u[0], &r[0], t);
109 for (i = 0; i < nlat; ++i)
111 for (j = 0; j < nlon; ++j)
113 double phi = -0.5 * M_PI + i * dlat;
114 double lambda = j * dlon;
116 v[i * nlon + j] = ans (phi, lambda, t);
117 //fprintf(stderr, "%.16lf %.16lf \n", u[i * nlon + j], v[i * nlon + j]);
121 nev1 = bv.dist(&u[0], &v[0]);
123 fprintf (stderr, "time=%lf nev1=%.16le \n", t, nev1);
131 inline double sign(double k)
140 double test_coriolis (double phi, double lambda)
142 return 2 * sin(phi) + 0.5 * cos(2 * lambda) * sign(2 * phi) * ipow(sin(2 * phi), 2);
145 void output_psi(const char * prefix, const char * suffix,
146 const double * psi, long nlat, long nlon,
147 double U0, double PSI0,
150 vector < double > u (nlat * nlon);
151 vector < double > v (nlat * nlon);
152 vector < double > Psi (nlat * nlon);
154 grad.calc(&u[0], &v[0], &psi[0]);
156 vec_mult_scalar(&u[0], &u[0], -1.0, nlat * nlon);
158 char ubuf[1024]; char vbuf[1024]; char psibuf[1024];
159 char Ubuf[1024]; char Vbuf[1024]; char Psibuf[1024];
161 snprintf(ubuf, 1024, "out/%snorm_u%s.txt", prefix, suffix);
162 snprintf(vbuf, 1024, "out/%snorm_v%s.txt", prefix, suffix);
163 snprintf(psibuf, 1024, "out/%snorm_psi%s.txt", prefix, suffix);
165 snprintf(Ubuf, 1024, "out/%sorig_u%s.txt", prefix, suffix);
166 snprintf(Vbuf, 1024, "out/%sorig_v%s.txt", prefix, suffix);
167 snprintf(Psibuf, 1024, "out/%sorig_psi%s.txt", prefix, suffix);
169 mat_print(ubuf, &u[0], nlat, nlon, "%23.16lf ");
170 mat_print(vbuf, &v[0], nlat, nlon, "%23.16lf ");
171 mat_print(psibuf, &psi[0], nlat, nlon, "%23.16lf ");
173 vec_mult_scalar(&u[0], &u[0], U0, nlon * nlat);
174 vec_mult_scalar(&v[0], &v[0], U0, nlon * nlat);
175 vec_mult_scalar(&Psi[0], &psi[0], PSI0, nlon * nlat);
177 mat_print(Ubuf, &u[0], nlat, nlon, "%23.16le ");
178 mat_print(Vbuf, &v[0], nlat, nlon, "%23.16le ");
179 mat_print(Psibuf, &Psi[0], nlat, nlon, "%23.16le ");
182 void run_test(const char * srtm)
187 SphereBarvortex::Conf conf;
191 conf.sigma = 1.14e-2;
192 int part_of_the_day = 48;
193 conf.tau = 2 * M_PI / (double) part_of_the_day;
198 conf.cor = 0;//test_coriolis;
200 double dlat = M_PI / (nlat - 1);
201 double dlon = 2. * M_PI / nlon;
203 double T = 2 * M_PI * 1000.0;
207 vector < double > u (nlat * nlon);
208 vector < double > v (nlat * nlon);
210 vector < double > r (nlat * nlon);
211 vector < double > f (nlat * nlon);
212 vector < double > cor(nlat * nlon);
213 vector < double > rel(nlat * nlon);
216 double omg = 2.*M_PI/24./60./60.; // ?
218 double RE = 6.371e+6;
219 double PSI0 = RE * RE / TE;
220 double U0 = 6.371e+6/TE;
221 const char * fn = srtm ? srtm : "";
224 FILE * f = fopen(fn, "rb");
226 size_t size = nlat * nlon * sizeof(double);
227 if (fread(&rel[0], 1, size, f) != size) {
228 fprintf(stderr, "bad relief file format ! \n");
231 fprintf(stderr, "relief file not found ! \n");
236 double rel_max = 0.0;
237 for (i = 0; i < nlat * nlon; ++i) {
238 if (rel_max < rel[i]) rel_max = rel[i];
239 //if (rel_max < fabs(rel[i])) rel_max = fabs(rel[i]);
242 for (i = 0; i < nlat; ++i)
244 for (j = 0; j < nlon; ++j)
246 double phi = -0.5 * M_PI + i * dlat;
247 double lambda = j * dlon;
249 //double ff = -(M_PI / 4 * ipow(phi, 2) - fabs(ipow(phi, 3)) / 3.0) * 16.0 / M_PI / M_PI * 3.0 / U0;
250 //r[i * nlon + j] = (phi > 0) ? ff : -ff;
252 u[i * nlon + j] = (phi * (M_PI / 2. - phi) * 16 / M_PI / M_PI * 30.0 / U0);
254 u[i * nlon + j] = (-phi * (M_PI / 2. + phi) * 16 / M_PI / M_PI * 30.0 / U0);
257 //cor[i * nlon + j] = conf.coriolis(phi, lambda);
259 //cor[i * nlon + j] = 1000 * rel[i * nlon + j] / rel_max + 2 * sin(phi);
262 // rel[i * nlon + j] = 0.5 * sign(phi) * cos(2 * lambda) * ipow(sin(2 * phi), 2);
264 if (rel[i * nlon + j] > 0) {
265 rel[i * nlon + j] = 1.0 * rel[i * nlon + j] / rel_max;
267 rel[i * nlon + j] = 0.0;
269 cor[i * nlon + j] = rel[i * nlon + j] + 2 * sin(phi);
273 SphereOperator op(nlat, nlon, 0);
274 SphereLaplace lapl(op);
276 SphereVorticity vor(op);
278 vor.calc(&f[0], &u[0], &v[0]);
280 vec_mult_scalar(&f[0], &f[0], -1.0, nlat * nlon);
282 for (i = 0; i < nlat; ++i)
284 for (j = 0; j < nlon; ++j)
286 double phi = -0.5 * M_PI + i * dlat;
288 f[i * nlon + j] *= -1.0;
293 lapl.solve(&r[0], &f[0]);
294 vec_mult_scalar(&f[0], &f[0], conf.sigma, nlat * nlon);
299 SphereBarvortex bv (conf);
301 Variance < double > var(u.size());
303 mat_print("out/cor.txt", &cor[0], nlat, nlon, "%23.16lf ");
304 mat_print("out/rel.txt", &rel[0], nlat, nlon, "%23.16lf ");
305 mat_print("out/rp.txt", &f[0], nlat, nlon, "%23.16lf ");
306 mat_print("out/u0.txt", &u[0], nlat, nlon, "%23.16lf ");
307 mat_print("out/v0.txt", &v[0], nlat, nlon, "%23.16lf ");
313 if (it % part_of_the_day == 0) {
316 if (isnan(nr)) break;
317 fprintf(stderr, "nr=%.16lf, t=%.16lf of %.16lf\n", nr, t, T);
318 snprintf(buf, 1024, "_%06d", it);
319 output_psi("", buf, &r[0], nlat, nlon, U0, PSI0, grad);
321 vector < double > m = var.m_current();
322 vector < double > d = var.current();
324 output_psi("m_", "", &m[0], nlat, nlon, U0, PSI0, grad);
325 output_psi("d_", "", &d[0], nlat, nlon, U0, PSI0, grad);
328 bv.S_step (&u[0], &r[0], t);
339 vector < double > m = var.m_current();
340 vector < double > d = var.current();
342 output_psi("m_", "", &m[0], nlat, nlon, U0, PSI0, grad);
343 output_psi("d_", "", &d[0], nlat, nlon, U0, PSI0, grad);
348 int main (int argc, char * argv[])
352 // exe [relief in binary format!]