1 /* Copyright (c) 2010 Alexey Ozeritsky
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "vorticity.h"
34 using namespace linal;
36 SphereLaplace::SphereLaplace (const SphereOperator & op) : SphereOperator(op)
40 SphereLaplace::~SphereLaplace() {}
42 void SphereLaplace::solve (double * out, const double * in, double mult, double diag)
48 double koef = -diag / mult;
50 array_t a (mdab * nlat);
51 array_t b (mdab * nlat);
52 array_t t (nlat * nlon);
54 mat_transpose1(&t[0], in, 1.0 / mult, nlat, nlon);
56 // находим разложение (a, b) по сферическим гармоникам
57 shaec_ (&nlat, &nlon, &isym, &nt, &t[0], &nlat, &nlon,
58 &a[0], &b[0], &mdab, &nlat, &swsave[0], &slsave,
59 &work[0], &lwork, &ierror);
60 // чтобы по разложению (a, b) собрать назад функцию надо воспользоваться
63 fprintf(stderr, "shaec_ error %ld\n", ierror);
67 islapec_ (&nlat, &nlon, &isym, &nt, &koef,
69 &a[0], &b[0], &mdab, &nlat,
70 &iswsave[0], &islsave, &work[0], &lwork, &pertrb, &ierror);
72 fprintf(stderr, "islapec_ error %ld\n", ierror);
76 mat_transpose(out, &t[0], nlon, nlat);
79 void SphereLaplace::calc(double * out, const double * in)
85 array_t a (mdab * nlat);
86 array_t b (mdab * nlat);
87 array_t t (nlat * nlon);
89 mat_transpose(&t[0], in, nlat, nlon);
91 shaec_ (&nlat, &nlon, &isym, &nt, &t[0],
92 &nlat, &nlon, &a[0], &b[0],
95 &work[0], &lwork, &ierror);
97 fprintf(stderr, "shaec_ error %ld\n", ierror);
100 slapec_ (&nlat, &nlon, &isym, &nt,
102 &a[0], &b[0], &mdab, &nlat,
103 &iswsave[0], &islsave, &work[0], &lwork, &ierror);
105 fprintf(stderr, "slapec_ error %ld\n", ierror);
109 mat_transpose(out, &t[0], nlon, nlat);
112 void SphereLaplace::make_psi(double * psi, const double * u, const double * v)
114 SphereVorticity vor (*this);
116 vor.calc (&psi[0], &u[0], &v[0]);
117 vec_mult_scalar (&psi[0], &psi[0], -1.0, nlat * nlon);