LORENE
tbl_val_smooth.C
1/*
2 * Smoothes the junction with an eventual atmosphere.
3 *
4 */
5
6/*
7 * Copyright (c) 2004 Jerome Novak
8 *
9 * This file is part of LORENE.
10 *
11 * LORENE is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2
13 * as published by the Free Software Foundation.
14 *
15 * LORENE is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with LORENE; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26
27
28
29/*
30 * $Id: tbl_val_smooth.C,v 1.5 2016/12/05 16:18:20 j_novak Exp $
31 * $Log: tbl_val_smooth.C,v $
32 * Revision 1.5 2016/12/05 16:18:20 j_novak
33 * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
34 *
35 * Revision 1.4 2014/10/13 08:53:49 j_novak
36 * Lorene classes and functions now belong to the namespace Lorene.
37 *
38 * Revision 1.3 2004/12/30 16:14:01 j_novak
39 * Changed the name of a shadowed variable.
40 *
41 * Revision 1.2 2004/12/03 13:24:01 j_novak
42 * Minor modif.
43 *
44 * Revision 1.1 2004/11/26 17:02:19 j_novak
45 * Added a function giving a smooth transition to the atmosphere.
46 *
47 *
48 * $Header: /cvsroot/Lorene/C++/Source/Valencia/tbl_val_smooth.C,v 1.5 2016/12/05 16:18:20 j_novak Exp $
49 *
50 */
51
52// Lorene headers
53#include "tbl_val.h"
54
55//Local prototypes
56namespace Lorene {
57void radial_smoothing(double* , const double* , int , double) ;
58//****************************************************************************
59
60void Tbl_val::smooth_atmosphere(double atmosphere_thr) {
61
62 const Gval_spher* gspher = dynamic_cast<const Gval_spher*>(gval) ;
63 assert(gspher != 0x0) ;
64 int ndim = gspher->get_ndim() ;
65 int fant = gspher->get_fantome() ;
66 int nr = get_dim(0) + 2*fant;
67
68 switch (ndim) {
69 case 1: {
70 radial_smoothing(t, gspher->zr->t, nr, atmosphere_thr) ;
71 break ;
72 }
73 case 2: {
74 int nt = get_dim(1) + 2*fant ;
75 for (int j=0; j<nt; j++)
76 radial_smoothing(t+j*nr, gspher->zr->t, nr, atmosphere_thr) ;
77 break ;
78 }
79 case 3: {
80 int nt = get_dim(1) + 2*fant ;
81 int np = get_dim(2) + 2*fant ;
82 for (int j=0; j<nt; j++)
83 for (int k=0; k<np; k++)
84 radial_smoothing(t+k*nt*nr+j*nr, gspher->zr->t, nr, atmosphere_thr) ;
85 break ;
86 }
87
88 default: {
89 cerr << "Tbl_val::smooth_atmosphere : strange number of dimensions!"
90 << endl ;
91 abort() ;
92 break ;
93 }
94 }
95 return ;
96}
97
98void radial_smoothing(double* tab, const double* rr, int n, double rho) {
99
100 assert((tab!= 0x0)&&(rr!=0x0)) ;
101 assert (rho >= 0.) ;
102
103 if (fabs(tab[n-1]) > rho) // no atmosphere here
104 return ;
105
106 double* t = tab + (n-1) ;
107 int indice = -1 ;
108 bool atmos = true ;
109 bool jump = false ;
110 for (int i=0; ((i<n)&&(atmos)); i++) {
111 if (atmos) atmos = ( fabs(*t) < rho) ;
112 t-- ;
113 if (atmos) {
114 jump = ( fabs(*t) > rho ) ;
115 if (jump) // discontinuity found
116 indice = n - i - 2 ;
117 }
118 }
119 if (indice == -1) return ;
120 int np = 2*(n-indice-2)/3 ;
121 int nm = indice / 100 + 3 ;
122 assert(n > nm+np) ;
123 if (indice < n - np+1) { // enough points to interpolate
124
125 // The inteprolation is done using a cubic polynomial
126 //---------------------------------------------------
127
128 int ileft = indice - nm + 2 ;
129 int iright = indice + np - 1 ;
130 double alpha = ( rr[ileft - 2] - rr[ileft - 1]) /
131 ( rr[ileft -1] - rr[ileft]) ;
132 double der_l = ( alpha*(alpha+2.)*tab[ileft]
133 - (1.+alpha)*(1.+alpha)*tab[ileft-1]
134 + tab[ileft-2] ) /
135 ( (1.+alpha)*(rr[ileft - 1] - rr[ileft - 2]) ) ;
136 double f_l = tab[ileft] ;
137 double f_r = tab[iright] ;
138 double tau = rr[ileft] - rr[iright] ;
139 double alp = der_l / (tau*tau) + 2.*(f_r - f_l)/(tau*tau*tau) ;
140 double bet = 0.5*(der_l + alp*tau*(rr[iright] - 3*rr[ileft])) / tau ;
141 for (int i=ileft; i<iright; i++) {
142 tab[i] = f_r + (alp*rr[i]+bet)*(rr[i] - rr[iright])*(rr[i] - rr[iright]);
143 }
144 }
145 else { // too few points to interpolate -> linear extrapolation ...
146 int ileft = indice ;
147 double alpha = ( rr[ileft - 2] - rr[ileft - 1]) /
148 ( rr[ileft -1] - rr[ileft]) ;
149 double der_l = ( alpha*(alpha+2.)*tab[ileft]
150 - (1.+alpha)*(1.+alpha)*tab[ileft-1]
151 + tab[ileft-2] ) /
152 ( (1.+alpha)*(rr[ileft - 1] - rr[ileft - 2]) ) ;
153 for (int i=ileft; i<n; i++) {
154 tab[i] = tab[ileft] + (rr[i] - rr[ileft])*der_l ;
155 }
156 }
157 return ;
158}
159}
const Grille_val * gval
The Grille_val (cartesian or spherical) on which the array is defined.
Definition tbl_val.h:110
int get_dim(int i) const
Gives the i th dimension (ie dim->dim[i] , without hidden cells).
Definition tbl_val.h:485
double * t
The array of double at the nodes.
Definition tbl_val.h:114
Lorene prototypes.
Definition app_hor.h:67