File: wave_impl_bc3.C

package info (click to toggle)
lorene 0.0.0~cvs20161116%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster, stretch
  • size: 26,444 kB
  • ctags: 13,953
  • sloc: cpp: 212,946; fortran: 21,645; makefile: 1,750; sh: 4
file content (186 lines) | stat: -rw-r--r-- 5,423 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include <math.h>

// Lorene headers
#include "metric.h"
#include "proto.h"
#include "graphique.h"
#include "diff.h"

double next_xi(double, double, double, double, double, int) ;

using namespace Lorene ;

int main() {

    // Construction of a multi-grid (Mg3d)
    // -----------------------------------
    
    const int nz = 1 ; 	// Only a nucleus
    int nr; 
    cout << "Enter nr: " << endl ;
    cin >> nr ; // Number of collocation points in r
    int nt = 5 ; 	// Number of collocation points in theta 
    int np = 6 ; 	// Number of collocation points in phi
    int symmetry_theta = SYM ; // symmetry with respect to the equatorial plane
    int symmetry_phi = SYM ; // symmetry in phi
    
    Mg3d mgrid(nz, nr, nt, np, symmetry_theta, symmetry_phi, false) ;
    
    // Construction of an affine mapping (Map_af)
    // ------------------------------------------
    
    double Rlim = 2. ;
    
    // Boundaries of each domains
    double r_limits[] = {0., Rlim} ; 
    
    Map_af map(mgrid, r_limits) ; 
    double alpha = map.get_alpha()[0] ;

    // Coordinate fields
    const Coord& r = map.r ;
    const Coord& x = map.x ;
    const Coord& y = map.y ;

    // Flat metric in spherical components
    //------------------------------------
    const Metric_flat& mets = map.flat_met_spher() ;
    
    // Initial data
    //-------------
    Scalar phim1(map) ;
    Scalar phi = phim1 ;

    // Time-step & boundary conditions
    //--------------------------------
    double dt ;
    cout << "Enter dt: " << endl ;
    cin >> dt ;
    int iter = 0 ;
    int ndes = int(Rlim / dt) / 200 + 1;

    // Some initializations
    //---------------------
    int l_q, m_q, base_r ;
    double emax = -1.e33 ;
    double emin = 1.e33 ;
    phi.set_spectral_va().ylm() ;
    const Base_val& base = phi.get_spectral_base() ;
    Mtbl_cf xi(mgrid.get_angu(), base) ;
    xi.annule_hard() ;
    Mtbl_cf xim1(mgrid.get_angu(), base) ;
    xim1.annule_hard() ;

    //----------------------------
    //         Main loop
    //----------------------------
    for (double tps=0.; tps<3.*Rlim; tps += dt) {
	
	// Crank-Nicholson 2nd-order scheme
	//---------------------------------
	Scalar source(map) ;
	phi.set_spectral_va().ylm() ;
	phim1.set_spectral_va().ylm() ;

	Mtbl_cf resu(mgrid, base) ;
	resu.annule_hard() ; //Initialized to zero
	    
    // Loop on theta, phi
    //-------------------
	for (int k=0; k<np; k++)
	    for (int j=0; j<nt; j++) 
		if (nullite_plm(j, nt, k, np, base) == 1) {
		    base.give_quant_numbers(0, k, j, m_q, l_q, base_r) ;
		    
		    // Recovering the elementary operators
		    //------------------------------------
		    Diff_sxdsdx dx(base_r, nr) ; const Matrice& mdx = dx.get_matrice() ;
		    Diff_dsdx2 dx2(base_r, nr) ; const Matrice& md2 = dx2.get_matrice() ;
		    Diff_sx2 sx2(base_r, nr) ; const Matrice& ms2 = sx2.get_matrice() ;
		    Diff_id id(base_r, nr) ; const Matrice& mid = id.get_matrice() ;
    
		    // Global operator (without BCs)
		    //------------------------------
		    Matrice ope(nr,nr) ;

		    // Boundary conditions on the last line
		    //-------------------------------------

		    Tbl rhs(nr) ; rhs.set_etat_qcq() ;
		    Tbl fi(nr) ; fi.set_etat_qcq() ;
		    Tbl fim1(nr) ; fim1.set_etat_qcq() ;
		    
		    for (int i=0; i<nr; i++) {
			rhs.set(i) = (*source.get_spectral_va().c_cf)(0, k, j, i) ;
			fi.set(i) = (*phi.get_spectral_va().c_cf)(nz-1, k, j, i) ;
			fim1.set(i) = (*phim1.get_spectral_va().c_cf)(nz-1, k, j, i) ;
		    }
		    double fi_1 = val1_dern_1d(0, fi, base_r) ;
		    double fim1_1 = val1_dern_1d(0, fim1, base_r) ;

		    // Enhanced outgoing BC (needs auxilliary equation to be solved)
		    //--------------------------------------------------------------
		    // To be done ....

		    // regularity conditions

		    // Solution of the system
		    //-----------------------
		    ope.set_lu() ;
		    Tbl sol = ope.inverse(rhs) ;
		    for (int i=0; i<nr; i++) 
			resu.set(0, k, j, i) = sol(i) ;
		}

	// Putting everything into place
	//------------------------------
	Scalar phip1(map) ;
	phip1.set_etat_qcq() ;
	phip1.set_spectral_va() = resu ;
	phip1.set_spectral_va().ylm_i() ;
	phi.set_spectral_va().ylm_i() ;
	phim1.set_spectral_va().ylm_i() ;

	// Energy calculation
	//-------------------
	Scalar dtphi = (phip1 - phim1)/(2*dt) ;
	double ener = (dtphi*dtphi 
		       + contract(phi.derive_con(mets), 0, 
				  phi.derive_cov(mets), 0)).integrale() ;
	
	emax = (ener > emax) ? ener : emax ;
	emin = (ener < emin) ? ener : emin ;
	
	cout << "Energy inside the grid: " << ener << endl ;
   
	// Drawing
	//--------
	if (iter%ndes == 0) {
	    des_meridian(phip1, 0., Rlim, "\\gf", 1) ;
	}
	    
	// Preparation for next step
	//--------------------------
	iter++ ;
	phim1 = phi ;
	phi = phip1 ;
    }
    cout << "Emin, Emax: " << emin << ", " << emax << endl ;
    cout << "Difference: " << (emax - emin) / emax << endl ;

    return EXIT_SUCCESS ; 
}

//----------------------------------------------------------------
// Auxilliary equation: wave-like equation on the boundary sphere
// 2nd-order Crank-Nicholson time-integration scheme
//----------------------------------------------------------------

// This might be usefull...
double next_xi(double xi, double xim1, double source, double Rlim, double dt,
	       int l_q) {

    double xip1 ; //\xi^{J+1}
    return xip1 ;

}