src/lapl.cpp
author Alexey Ozeritsky <aozeritsky@gmail.com>
Fri Jun 11 21:50:18 2010 +0400 (20 months ago)
changeset 142 2aa3b89e9ccc
parent 1310b178b55bd4a
child 16502918a8f3015
permissions -rw-r--r--
fix
     1 /* Copyright (c) 2010 Alexey Ozeritsky
     2  * All rights reserved.
     3  *
     4  * Redistribution and use in source and binary forms, with or without
     5  * modification, are permitted provided that the following conditions
     6  * are met:
     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
    14  *
    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.
    25  */
    26 
    27 #include <stdio.h>
    28 #include <stdlib.h>
    29 
    30 #include "lapl.h"
    31 #include "vorticity.h"
    32 #include "linal.h"
    33 
    34 using namespace linal;
    35 
    36 SphereLaplace::SphereLaplace (const SphereOperator & op) : SphereOperator(op)
    37 {
    38 }
    39 
    40 SphereLaplace::~SphereLaplace() {}
    41 
    42 void SphereLaplace::solve (double * out, const double * in, double mult, double diag)
    43 {
    44 	long ierror = 0;
    45 	long nt   = 1;
    46 
    47 	double pertrb = 0;
    48 	double koef   = -diag / mult;
    49 
    50 	array_t a (mdab * nlat);
    51 	array_t b (mdab * nlat);
    52 	array_t t (nlat * nlon);
    53 
    54 	mat_transpose1(&t[0], in, 1.0 / mult, nlat, nlon);
    55 
    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) собрать назад функцию надо воспользоваться
    61 	// функцией shsec_
    62 	if (ierror != 0) {
    63 		fprintf(stderr, "shaec_ error %ld\n", ierror);
    64 		exit(1);
    65 	}
    66 
    67 	islapec_ (&nlat, &nlon, &isym, &nt, &koef,
    68 	          &t[0], &nlat, &nlon,
    69 	          &a[0], &b[0], &mdab, &nlat,
    70 	          &iswsave[0], &islsave, &work[0], &lwork, &pertrb, &ierror);
    71 	if (ierror != 0) {
    72 		fprintf(stderr, "islapec_ error %ld\n", ierror);
    73 		exit(1);
    74 	}
    75 
    76 	mat_transpose(out, &t[0], nlon, nlat);
    77 }
    78 
    79 void SphereLaplace::calc(double * out, const double * in)
    80 {
    81 	long ierror = 0;
    82 	long nt = 1;
    83 	long isym = 0;
    84 
    85 	array_t a (mdab * nlat);
    86 	array_t b (mdab * nlat);
    87 	array_t t (nlat * nlon);
    88 
    89 	mat_transpose(&t[0], in, nlat, nlon);
    90 
    91 	shaec_ (&nlat, &nlon, &isym, &nt, &t[0],
    92 	        &nlat, &nlon, &a[0], &b[0],
    93 	        &mdab, &nlat,
    94 	        &swsave[0], &slsave,
    95 	        &work[0], &lwork, &ierror);
    96 	if (ierror != 0) {
    97 		fprintf(stderr, "shaec_ error %ld\n", ierror);
    98 		exit(1);
    99 	}
   100 	slapec_ (&nlat, &nlon, &isym, &nt, 
   101 	          &t[0], &nlat, &nlon,
   102 	          &a[0], &b[0], &mdab, &nlat,
   103 	          &iswsave[0], &islsave, &work[0], &lwork, &ierror);
   104 	if (ierror != 0) {
   105 		fprintf(stderr, "slapec_ error %ld\n", ierror);
   106 		exit(1);
   107 	}
   108 
   109 	mat_transpose(out, &t[0], nlon, nlat);
   110 }
   111 
   112 void SphereLaplace::make_psi(double * psi, const double * u, const double * v)
   113 {
   114 	SphereVorticity vor (*this);
   115 
   116 	vor.calc (&psi[0], &u[0], &v[0]);
   117 	vec_mult_scalar (&psi[0], &psi[0], -1.0, nlat * nlon);
   118 }
   119