C/C++ source
0001 /* 0002 0003 raytracing.c MEX file implementation of a universal ray-tracing for electron waves 0004 0005 call -> [tout, yout, yproc] = raytracing_yp(rayparam,equil,y0) 0006 0007 INPUT: 0008 0009 - rayparam: parameters for ray-tracing structure [1,1] 0010 - equil: numerical equilibrium structure [1,1] 0011 - y0: ray initial conditions [1,1] 0012 0013 OUTPUT: 0014 0015 - tout: returned integration time points (row-vector). 0016 - yout: returned solution, one solution column-vector per tout-value. 0017 - yproc: returned processed data, one set of data as column-vector per tout-value. 0018 0019 WARNING: none 0020 0021 REFERENCE: none 0022 0023 by Y.PEYSSON (CEA-IRFM) <yves.peysson@cea.fr>, Joan Decker (CEA-IRFM) <joan.decker@cea.fr> and Laurent Colas (CEA-IRFM) <laurent.colas@cea.fr> 0024 Guillaume Brochard <guillaume.brochard@cea.fr>*/ 0025 0026 #define DUMP(u) mexPrintf("%s = %e\n", #u, u) 0027 0028 #include <complex.h> 0029 #include <math.h> 0030 #include "mex.h" 0031 #include "structures_raytracing_yp.h" 0032 0033 /* Input Arguments */ 0034 0035 #define RAYPARAM_IN prhs[0] 0036 #define EQUIL_IN prhs[1] 0037 #define Y0_IN prhs[2] 0038 #define DISTRI_IN prhs[3] 0039 #define FLUCT_IN prhs[4] 0040 #define FLAG_IN prhs[5] 0041 0042 0043 /* Output Arguments */ 0044 0045 #define T_OUT plhs[0] 0046 #define Y_OUT plhs[1] 0047 #define Y_PROC plhs[2] 0048 0049 #define MC 8 0050 #define MPROC 26 0051 #define SAFETY 0.8 0052 #define PGROW 0.2 0053 #define PSHRINK 0.25 0054 #define PI 3.14159265358979 0055 #define CLUM 299792458 /*Speed of light (m/s) */ 0056 0057 /* Fehlberg coefficients fro the 45 Runge-Kutta integration */ 0058 0059 static double alpha[5] = { 1.0/4.0, 3.0/8.0, 12.0/13.0, 1.0, 1.0/2.0 }; 0060 0061 static double beta[5][5] = { 0062 { 1.0/4.0, 3.0/32.0, 1932.0/2197.0, 8341.0/4104.0, -6080.0/20520.0 }, 0063 { 0.0, 9.0/32.0, -7200.0/2197.0, -32832.0/4104.0, 41040.0/20520.0 }, 0064 { 0.0, 0.0, 7296.0/2197.0, 29440.0/4104.0, -28352.0/20520.0 }, 0065 { 0.0, 0.0, 0.0, -845.0/4104.0, 9295.0/20520.0 }, 0066 { 0.0, 0.0, 0.0, 0.0, -5643.0/20520.0 } 0067 }; 0068 0069 static double gama[6][2] = { 0070 { 902880.0/7618050.0, -2090.0/752400.0 }, 0071 { 0.0, 0.0 }, 0072 { 3953664.0/7618050.0, 22528.0/752400.0 }, 0073 { 3855735.0/7618050.0, 21970.0/752400.0 }, 0074 { -1371249.0/7618050.0, -15048.0/752400.0 }, 0075 { 277020.0/7618050.0, -27360.0/752400.0 } 0076 }; 0077 0078 0079 void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 0080 0081 rayparam_format rayparam; 0082 equilparam_format equilparam; 0083 fluctparam_format fluctparam; 0084 raymagnetic_format raymagnetic; 0085 rayprofiles_format rayprofiles; 0086 susceptibilitytensor_format X; 0087 rayfluctuations_format rayfluctuations; 0088 rayequil_format rayequil; 0089 distriparam_format distriparam; 0090 raydistri_format raydistri; 0091 0092 double flag,flag_proc = 1; 0093 0094 register int i,j; 0095 int flag_fluct = 1,flag_f0 = 1,flag_metric = 1; 0096 int fmode,nss,iss,ns; 0097 double dummy,dummy10[3],dummy11[4],dummy12[4]; 0098 0099 mxArray *tmp; 0100 0101 /* For Runge-Kutta integration */ 0102 0103 double *tout,*yout,*yproc; 0104 double *toutp,*youtp; 0105 double *y0,*y1,*yinit,*y0_in,*y0dot; 0106 double tau_lim; 0107 0108 register unsigned int m,kk,ii=0; 0109 register int k=-1; 0110 0111 int flag1,iimax=200000, kmax; 0112 0113 double *s0,*s1,*s2,*s3,*s4,*s5,*s6; 0114 double *tempt,*temp0,*temp1,*temp2,*temp3,*temp4,*temp5,*temp6,*temp7; 0115 0116 double ymax,tau,delta,h,hmax,hmin; 0117 0118 double ydel[MC],ys[7]; 0119 0120 double t1,t2,ts,rho1,rho2,theta1,theta2,z1,z2,krho1,krho2,m1,m2,kz1,kz2,omega1,omega2; 0121 0122 double rhodot,thetadot,zdot,krhodot,mdot,kzdot,omegadot,Sdot; 0123 0124 double S1,S2,S_step,Sdot1,Sdot2,Sdot3,Sdot4,Sdot5,Sdot6; 0125 0126 double *rayproc,**temp_proc; 0127 double dS,depth=0.0,alpha1=0.0,alpha2,absphi; 0128 0129 double alpha_rho,alpha_theta,alpha_z,acc,krho1_dsolve; 0130 0131 /* Check out input and output arguments */ 0132 0133 if (nrhs < 3 || nrhs > 6) mexErrMsgTxt("Wrong number of input arguments for raytracing_yp.mex");/* The number of input arguments is fixed */ 0134 0135 if (!mxIsStruct(prhs[0])) mexErrMsgTxt("1st input argument of raytracing_yp.mex must be a structure (rayparam)"); 0136 0137 if (nrhs == 3) { 0138 flag = 0; 0139 flag_f0 = 0; 0140 flag_fluct = 0; 0141 if (!mxIsStruct(prhs[1])) mexErrMsgTxt("2nd input argument of raytracing_yp.mex must be a structure (equil_fit)"); 0142 } 0143 0144 if (nrhs == 4) { 0145 flag = 0;/* Numerical toroidal MHD equilibrium */ 0146 flag_fluct = 0;/* No fluctuations */ 0147 if (!mxIsStruct(prhs[1])) mexErrMsgTxt("2nd input argument of raytracing_yp.mex must be a structure (equil_fit)"); 0148 if (!mxIsStruct(prhs[3])) flag_f0 = 0;/* fourth input argument must be a structure for wave damping on a non-maxwellian distribution */ 0149 if (mxIsEmpty(prhs[3])) flag_f0 = 0;/* if empty, wave damping on maxwellian distribution only */ 0150 } 0151 0152 if (nrhs > 4) { 0153 if (!mxIsStruct(prhs[3])) flag_f0 = 0;/* fourth input argument must be a structure for wave damping on a non-maxwellian distribution */ 0154 if (mxIsEmpty(prhs[3])) flag_f0 = 0;/* if empty, wave damping on maxwellian distribution only */ 0155 if (!mxIsStruct(prhs[4])) flag_fluct = 0;/* fifth input argument must be a structure for plasma fluctuations */ 0156 if (mxIsEmpty(prhs[4])) flag_fluct = 0;/* if empty, no plasma fluctuations */ 0157 0158 if (nrhs == 5) { 0159 flag = 0;/* Numerical toroidal MHD equilibrium */ 0160 if (!mxIsStruct(prhs[1])) mexErrMsgTxt("2nd input argument of raytracing_yp.mex must be a structure (equil_fit)"); 0161 } else { 0162 if (mxIsEmpty(prhs[5])) { 0163 flag = 0;/* Numerical toroidal MHD equilibrium */ 0164 } else { 0165 flag = *(mxGetPr(FLAG_IN));/* Numerical toroidal MHD equilibrium or analytical tests */ 0166 } 0167 if (fabs(flag) > 0) { 0168 mexPrintf("WARNING: Plasma fluctuations are incompatible with the analytical toroidal MHD magnetic equilibrium option.\n"); 0169 flag_f0 = 0; 0170 flag_fluct = 0; 0171 } 0172 } 0173 } 0174 0175 /* mexPrintf("flag : %d\n",abs(flag)); */ 0176 0177 if (nlhs < 2 || nlhs > 3) mexErrMsgTxt("Wrong number of output arguments for raytracing_yp.mex***"); 0178 if (nlhs == 2) flag_proc = 0;/* flag for calculating additional ray data */ 0179 0180 /* 0181 double complex iBn,iBnp,iBnpp; 0182 modBessel(-5.4,(double complex)(3.0 +1.2*I),&iBn,&iBnp,&iBnpp); 0183 mexPrintf("Bessel(-5.4,3.+1.2*i),Bp,Bpp:%g,%g,%g,%g,%g,%g\n",iBn,iBnp,iBnpp); 0184 */ 0185 0186 /* Get Input Arguments */ 0187 0188 rayparam = load_ray_param(RAYPARAM_IN); 0189 0190 if (isinf(rayparam.tau_lim[0])) { 0191 tau_lim = -1.0; 0192 } else { 0193 tau_lim = rayparam.tau_lim[0]; 0194 } 0195 kmax = (int)rayparam.kmax[0]; 0196 0197 y0_in = mxGetPr(Y0_IN); 0198 0199 if (flag == 0) {/* numerical toroidal MHD equilibrium */ 0200 equilparam = load_equil_param(EQUIL_IN); 0201 0202 if ((isinf(equilparam.Rp[0]) == 1) & (flag_fluct > 0)) { 0203 mexPrintf("WARNING: Plasma fluctuations are incompatible with the cylindrical toroidal MHD magnetic equilibrium.\n"); 0204 flag_f0 = 0; 0205 flag_fluct = 0; 0206 } 0207 0208 ns = equilparam.ns[0];/* number of species for memory allocation */ 0209 0210 if (equilparam.zZi[0] > 0) {/*Vacuum case otherwise (no density, temperature...)*/ 0211 rayequil.Te_fit = load_profile_1D(EQUIL_IN,"Te_fit"); 0212 rayequil.ne_fit = load_profile_1D(EQUIL_IN,"ne_fit"); 0213 rayequil.zTi_fit = load_profile_1D(EQUIL_IN,"zTi_fit"); 0214 rayequil.zni_fit = load_profile_1D(EQUIL_IN,"zni_fit"); 0215 } 0216 0217 rayequil.x_fit = load_grid_2D(EQUIL_IN,"x_fit",0); 0218 rayequil.y_fit = load_grid_2D(EQUIL_IN,"y_fit",0); 0219 rayequil.r_fit = load_grid_2D(EQUIL_IN,"r_fit",0); 0220 rayequil.calpha_fit = load_grid_2D(EQUIL_IN,"calpha_fit",0); 0221 rayequil.salpha_fit = load_grid_2D(EQUIL_IN,"salpha_fit",0); 0222 rayequil.gradrho_fit = load_grid_2D(EQUIL_IN,"gradrho_fit",0); 0223 0224 rayequil.Bx_fit = load_grid_2D(EQUIL_IN,"Bx_fit",0); 0225 rayequil.By_fit = load_grid_2D(EQUIL_IN,"By_fit",0); 0226 rayequil.Bz_fit = load_grid_2D(EQUIL_IN,"Bz_fit",0); 0227 rayequil.BP_fit = load_grid_2D(EQUIL_IN,"BP_fit",0); 0228 rayequil.B_fit = load_grid_2D(EQUIL_IN,"B_fit",0); 0229 0230 if (flag_f0 == 1) { 0231 distriparam = load_distri_param(DISTRI_IN); 0232 raydistri.f0_fit = load_profile_1D(DISTRI_IN,"XXf0_fit"); 0233 raydistri.PSI_fit = load_grid_2D(DISTRI_IN,"PSI_fit",0); 0234 } 0235 0236 if (flag_fluct == 1) { 0237 fluctparam = load_fluct_param(FLUCT_IN); 0238 rayfluctuations.L_rho = load_value_0D(FLUCT_IN,"L_rho"); 0239 rayfluctuations.xq_fit = load_profile_1D(FLUCT_IN,"xq_fit"); 0240 rayfluctuations.xL_theta_fit = load_profile_1D(FLUCT_IN,"xL_theta_fit"); 0241 rayfluctuations.xL_perp_fit = load_profile_1D(FLUCT_IN,"xL_perp_fit"); 0242 rayfluctuations.XL_phi_fit = load_grid_2D(FLUCT_IN,"XL_phi_fit",0); 0243 rayfluctuations.Xcm_fit = load_grid_2D(FLUCT_IN,"Xcm_fit",0); 0244 rayfluctuations.Xcn_fit = load_grid_2D(FLUCT_IN,"Xcn_fit",0); 0245 0246 if (fluctparam.ne_nmodel[0]) { 0247 tmp = mxGetField(FLUCT_IN, 0,"ne_fit"); 0248 nss = fmax(mxGetDimensions(tmp)[0],mxGetDimensions(tmp)[1]); 0249 } 0250 0251 if (fluctparam.B_nmodel[0]) { 0252 tmp = mxGetField(FLUCT_IN, 0,"B_fit"); 0253 nss = fmax(mxGetDimensions(tmp)[0],mxGetDimensions(tmp)[1]); 0254 0255 rayfluctuations.B_sfx_fit = mxCalloc(nss,sizeof(pp_2D_format)); 0256 rayfluctuations.B_sfy_fit = mxCalloc(nss,sizeof(pp_2D_format)); 0257 rayfluctuations.B_sfz_fit = mxCalloc(nss,sizeof(pp_2D_format));/* here z stands for phi, the toroidal direction */ 0258 0259 for (iss = 0;iss < nss; iss++) { 0260 rayfluctuations.B_sfx_fit[iss] = load_grid_2D(tmp,"Xfx_fit",iss); 0261 rayfluctuations.B_sfy_fit[iss] = load_grid_2D(tmp,"Xfy_fit",iss); 0262 rayfluctuations.B_sfz_fit[iss] = load_grid_2D(tmp,"Xfz_fit",iss);/* here z stands for phi, the toroidal direction */ 0263 } 0264 } 0265 0266 } else { 0267 fluctparam.ne_nmodel = mxCalloc(1,sizeof(int));/* automatic set to zero by default */ 0268 fluctparam.B_nmodel = mxCalloc(1,sizeof(int));/* automatic set to zero by default */ 0269 } 0270 } else { 0271 0272 load_idealequil_test(flag,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&dummy,&ns,dummy10,dummy11,dummy12,&dummy);/* number of species for memory allocation */ 0273 0274 equilparam.zZi = mxCalloc(ns,sizeof(double)); 0275 equilparam.zmi = mxCalloc(ns,sizeof(double)); 0276 equilparam.ns = mxCalloc(1,sizeof(int)); 0277 equilparam.Rp = mxCalloc(1,sizeof(double)); 0278 equilparam.ap = mxCalloc(1,sizeof(double)); 0279 equilparam.Zp = mxCalloc(1,sizeof(double)); 0280 equilparam.psia_apRp = mxCalloc(1,sizeof(double)); 0281 0282 fluctparam.ne_nmodel = mxCalloc(1,sizeof(int));/* automatic set to zero by default */ 0283 fluctparam.B_nmodel = mxCalloc(1,sizeof(int));/* automatic set to zero by default */ 0284 } 0285 0286 0287 /* Memory allocation */ 0288 0289 raymagnetic.rn = mxCalloc(1,sizeof(double)); 0290 raymagnetic.xn = mxCalloc(1,sizeof(double)); 0291 raymagnetic.yn = mxCalloc(1,sizeof(double)); 0292 raymagnetic.Brhon = mxCalloc(1,sizeof(double)); 0293 raymagnetic.Bsn = mxCalloc(1,sizeof(double)); 0294 raymagnetic.Bzn = mxCalloc(1,sizeof(double)); 0295 raymagnetic.B = mxCalloc(1,sizeof(double)); 0296 raymagnetic.salpha = mxCalloc(1,sizeof(double)); 0297 raymagnetic.calpha = mxCalloc(1,sizeof(double)); 0298 raymagnetic.gradrhon = mxCalloc(1,sizeof(double)); 0299 raymagnetic.rhorip = mxCalloc(1,sizeof(double)); 0300 raymagnetic.Upsilonn = mxCalloc(1,sizeof(double)); 0301 0302 raymagnetic.drndY = mxCalloc(MC,sizeof(double)); 0303 raymagnetic.dxndY = mxCalloc(MC,sizeof(double)); 0304 raymagnetic.dyndY = mxCalloc(MC,sizeof(double)); 0305 raymagnetic.dBrhondY = mxCalloc(MC,sizeof(double)); 0306 raymagnetic.dBsndY = mxCalloc(MC,sizeof(double)); 0307 raymagnetic.dBzndY = mxCalloc(MC,sizeof(double)); 0308 raymagnetic.dBdY = mxCalloc(MC,sizeof(double)); 0309 raymagnetic.dsalphadY = mxCalloc(MC,sizeof(double)); 0310 raymagnetic.dcalphadY = mxCalloc(MC,sizeof(double)); 0311 raymagnetic.dgradrhondY = mxCalloc(MC,sizeof(double)); 0312 raymagnetic.drhoripdY = mxCalloc(MC,sizeof(double)); 0313 raymagnetic.dUpsilonndY = mxCalloc(MC,sizeof(double)); 0314 0315 raymagnetic.d2rndY2 = mxCalloc(MC,sizeof(double)); 0316 raymagnetic.d2xndY2 = mxCalloc(MC,sizeof(double)); 0317 raymagnetic.d2yndY2 = mxCalloc(MC,sizeof(double)); 0318 raymagnetic.d2BrhondY2 = mxCalloc(MC,sizeof(double)); 0319 raymagnetic.d2BsndY2 = mxCalloc(MC,sizeof(double)); 0320 raymagnetic.d2BzndY2 = mxCalloc(MC,sizeof(double)); 0321 raymagnetic.d2BdY2 = mxCalloc(MC,sizeof(double)); 0322 raymagnetic.d2salphadY2 = mxCalloc(MC,sizeof(double)); 0323 raymagnetic.d2calphadY2 = mxCalloc(MC,sizeof(double)); 0324 raymagnetic.d2gradrhondY2 = mxCalloc(MC,sizeof(double)); 0325 raymagnetic.d2rhoripdY2 = mxCalloc(MC,sizeof(double)); 0326 raymagnetic.d2UpsilonndY2 = mxCalloc(MC,sizeof(double)); 0327 0328 for (i = 0;i < MC; i++) {/*initialisation */ 0329 raymagnetic.drndY[i] = 0.0; 0330 raymagnetic.dxndY[i] = 0.0; 0331 raymagnetic.dyndY[i] = 0.0; 0332 raymagnetic.dsalphadY[i] = 0.0; 0333 raymagnetic.dcalphadY[i] = 0.0; 0334 raymagnetic.dgradrhondY[i] = 0.0; 0335 raymagnetic.dBrhondY[i] = 0.0; 0336 raymagnetic.dBsndY[i] = 0.0; 0337 raymagnetic.dBzndY[i] = 0.0; 0338 raymagnetic.dBdY[i] = 0.0; 0339 raymagnetic.drhoripdY[i] = 0.0; 0340 raymagnetic.dUpsilonndY[i] = 0.0; 0341 0342 raymagnetic.d2rndY2[i] = 0.0; 0343 raymagnetic.d2xndY2[i] = 0.0; 0344 raymagnetic.d2yndY2[i] = 0.0; 0345 raymagnetic.d2salphadY2[i] = 0.0; 0346 raymagnetic.d2calphadY2[i] = 0.0; 0347 raymagnetic.d2gradrhondY2[i] = 0.0; 0348 raymagnetic.d2BrhondY2[i] = 0.0; 0349 raymagnetic.d2BsndY2[i] = 0.0; 0350 raymagnetic.d2BzndY2[i] = 0.0; 0351 raymagnetic.d2BdY2[i] = 0.0; 0352 raymagnetic.d2rhoripdY2[i] = 0.0; 0353 raymagnetic.d2UpsilonndY2[i] = 0.0; 0354 } 0355 0356 rayprofiles.Te = mxCalloc(1,sizeof(double)); 0357 rayprofiles.ne = mxCalloc(1,sizeof(double)); 0358 0359 rayprofiles.dTedY = mxCalloc(MC,sizeof(double)); 0360 rayprofiles.dnedY = mxCalloc(MC,sizeof(double)); 0361 rayprofiles.d2TedY2 = mxCalloc(MC,sizeof(double)); 0362 rayprofiles.d2nedY2 = mxCalloc(MC,sizeof(double)); 0363 0364 rayprofiles.zTi = mxCalloc(ns,sizeof(double)); 0365 rayprofiles.zni = mxCalloc(ns,sizeof(double)); 0366 0367 rayprofiles.dzTidY = mxCalloc(ns,sizeof(double *)); 0368 rayprofiles.dznidY = mxCalloc(ns,sizeof(double *)); 0369 rayprofiles.d2zTidY2 = mxCalloc(ns,sizeof(double *)); 0370 rayprofiles.d2znidY2 = mxCalloc(ns,sizeof(double *)); 0371 0372 for (i = 0;i < ns; i++) { 0373 rayprofiles.dzTidY[i] = mxCalloc(MC,sizeof(double)); 0374 rayprofiles.dznidY[i] = mxCalloc(MC,sizeof(double)); 0375 rayprofiles.d2zTidY2[i] = mxCalloc(MC,sizeof(double)); 0376 rayprofiles.d2znidY2[i] = mxCalloc(MC,sizeof(double)); 0377 } 0378 0379 /* Array initialisation */ 0380 0381 for (i = 0;i < MC; i++) { 0382 rayprofiles.dTedY[i] = 0.0; 0383 rayprofiles.dnedY[i] = 0.0; 0384 rayprofiles.d2TedY2[i] = 0.0; 0385 rayprofiles.d2nedY2[i] = 0.0; 0386 0387 for (j=0;jdouble complex)); 0396 X.Xxy = mxCalloc(1,sizeof(double complex)); 0397 X.Xxz = mxCalloc(1,sizeof(double complex)); 0398 X.Xyy = mxCalloc(1,sizeof(double complex)); 0399 X.Xyz = mxCalloc(1,sizeof(double complex)); 0400 X.Xzz = mxCalloc(1,sizeof(double complex)); 0401 0402 X.dXxxdNperp = mxCalloc(1,sizeof(double complex)); 0403 X.dXxydNperp = mxCalloc(1,sizeof(double complex)); 0404 X.dXxzdNperp = mxCalloc(1,sizeof(double complex)); 0405 X.dXyydNperp = mxCalloc(1,sizeof(double complex)); 0406 X.dXyzdNperp = mxCalloc(1,sizeof(double complex)); 0407 X.dXzzdNperp = mxCalloc(1,sizeof(double complex)); 0408 0409 X.dXxxdNpar = mxCalloc(1,sizeof(double complex)); 0410 X.dXxydNpar = mxCalloc(1,sizeof(double complex)); 0411 X.dXxzdNpar = mxCalloc(1,sizeof(double complex)); 0412 X.dXyydNpar = mxCalloc(1,sizeof(double complex)); 0413 X.dXyzdNpar = mxCalloc(1,sizeof(double complex)); 0414 X.dXzzdNpar = mxCalloc(1,sizeof(double complex)); 0415 0416 X.dXxxdY = mxCalloc(MC,sizeof(double complex)); 0417 X.dXxydY = mxCalloc(MC,sizeof(double complex)); 0418 X.dXxzdY = mxCalloc(MC,sizeof(double complex)); 0419 X.dXyydY = mxCalloc(MC,sizeof(double complex)); 0420 X.dXyzdY = mxCalloc(MC,sizeof(double complex)); 0421 X.dXzzdY = mxCalloc(MC,sizeof(double complex)); 0422 0423 for (i=0;i /*initialisation */ 0424 X.dXxxdY[i] = 0.0; 0425 X.dXxydY[i] = 0.0; 0426 X.dXxzdY[i] = 0.0; 0427 X.dXyydY[i] = 0.0; 0428 X.dXyzdY[i] = 0.0; 0429 X.dXzzdY[i] = 0.0; 0430 } 0431 0432 /* Create arguments for calling user function */ 0433 0434 tempt = mxCalloc(rayparam.kmax[0],sizeof(double)); 0435 temp0 = mxCalloc(rayparam.kmax[0],sizeof(double)); 0436 temp1 = mxCalloc(rayparam.kmax[0],sizeof(double)); 0437 temp2 = mxCalloc(rayparam.kmax[0],sizeof(double)); 0438 temp3 = mxCalloc(rayparam.kmax[0],sizeof(double)); 0439 temp4 = mxCalloc(rayparam.kmax[0],sizeof(double)); 0440 temp5 = mxCalloc(rayparam.kmax[0],sizeof(double)); 0441 temp6 = mxCalloc(rayparam.kmax[0],sizeof(double)); 0442 temp7 = mxCalloc(rayparam.kmax[0],sizeof(double)); 0443 0444 y0 = mxCalloc(MC,sizeof(double)); 0445 yinit = mxCalloc(MC,sizeof(double)); 0446 y0dot = mxCalloc(MC,sizeof(double)); 0447 y1 = mxCalloc(MC,sizeof(double)); 0448 s0 = mxCalloc(MC,sizeof(double)); 0449 s1 = mxCalloc(MC,sizeof(double)); 0450 s2 = mxCalloc(MC,sizeof(double)); 0451 s3 = mxCalloc(MC,sizeof(double)); 0452 s4 = mxCalloc(MC,sizeof(double)); 0453 s5 = mxCalloc(MC,sizeof(double)); 0454 s6 = mxCalloc(MC,sizeof(double)); 0455 0456 if (flag_proc == 1) { 0457 0458 rayproc = mxCalloc(MPROC+2*ns,sizeof(double));; 0459 0460 temp_proc = mxCalloc(MPROC+2*ns+1,sizeof(double *)); 0461 for (i = 0;i < MPROC+2*ns+1; i++) { 0462 temp_proc[i] = mxCalloc(rayparam.kmax[0],sizeof(double)); 0463 } 0464 0465 for (i = 0;i < MPROC+2*ns+1; i++) {/*initialisation */ 0466 for (kk = 0;kk < rayparam.kmax[0]; kk++) { 0467 temp_proc[i][kk] = 0.0; 0468 } 0469 } 0470 0471 } 0472 0473 /* Test Input Arguments */ 0474 0475 if (rayparam.testmode[0] > 0) testparam(rayparam,equilparam,fluctparam,raymagnetic,rayprofiles,rayequil,rayfluctuations,distriparam,raydistri,flag_fluct,flag_f0,flag,y0_in); 0476 /***************************************************************************/ 0477 /******************************* Runge-Kutta ******************************/ 0478 /***************************************************************************/ 0479 0480 0481 /* Create and Initialize Return Arguments */ 0482 0483 y0[0] = y0_in[0];/* Necessary to separe data from mex and matlab */ 0484 y0[1] = y0_in[1]; 0485 y0[2] = y0_in[2]; 0486 y0[3] = y0_in[3]; 0487 y0[4] = y0_in[4]; 0488 y0[5] = y0_in[5]; 0489 y0[6] = y0_in[6]; 0490 0491 0492 t1 = rayparam.t0[0]; 0493 0494 rho1 = y0[0]; 0495 theta1 = y0[1]; 0496 z1 = y0[2]; 0497 krho1 = y0[3]; 0498 m1 = y0[4]; 0499 kz1 = y0[5]; 0500 omega1 = y0[6]; 0501 0502 0503 yinit[0] = y0[0]; 0504 yinit[1] = y0[1]; 0505 yinit[2] = y0[2]; 0506 yinit[3] = y0[3]; 0507 yinit[4] = y0[4]; 0508 yinit[5] = y0[5]; 0509 yinit[6] = y0[6]; 0510 0511 S1 = 0.0; /* initial value of path length */ 0512 S_step = S1;/* initial path position */ 0513 0514 /* Solves the dispersion relation internally to remove numerical errors from initial conditions */ 0515 0516 0517 if (flag == 0) { 0518 interpequil(rayparam,raymagnetic,rayprofiles,equilparam,fluctparam,yinit,y0,rayequil,rayfluctuations,flag_fluct,flag_metric); 0519 } else { 0520 interpequil_test(raymagnetic,rayprofiles,equilparam,yinit,flag); 0521 } 0522 0523 0524 alpha_rho = raymagnetic.gradrhon[0]*raymagnetic.drhoripdY[0]; 0525 alpha_theta = raymagnetic.drhoripdY[1]/raymagnetic.rn[0]; 0526 alpha_z = raymagnetic.drhoripdY[2]/raymagnetic.Upsilonn[0]; 0527 0528 acc = raymagnetic.Brhon[0]*(alpha_rho - alpha_theta*raymagnetic.salpha[0]) + raymagnetic.Bsn[0]*alpha_theta*raymagnetic.calpha[0] + alpha_z*raymagnetic.Bzn[0]; 0529 0530 mexPrintf("Initial accuracy :%g\n",acc); 0531 0532 if ((fabs(flag) > 0) || (acc != 0)){ 0533 /* mexPrintf("krho1:%g\n",krho1); */ 0534 0535 dsolve(1,ns,&krho1_dsolve,yinit,y0,raymagnetic,rayprofiles,X,rayparam,equilparam,fluctparam,rayequil,rayfluctuations,flag,flag_fluct); 0536 0537 if (acc != 0) mexPrintf("The dispersion relation is first solved internally to remove numerical errors from initial conditions.\n"); 0538 0539 if (fabs((krho1_dsolve - krho1)/krho1) > 1e-3) { 0540 mexPrintf("WARNING: The relative difference between initial krho and krho after dsolve exceeds 1e-3.\n"); 0541 mexPrintf("krho1,krho1_dsolve:%g,%g\n",krho1,krho1_dsolve); 0542 krho1 = krho1_dsolve; 0543 } 0544 } 0545 /* Initialization */ 0546 ts = 100.0*rayparam.tfinal[0]; 0547 h = rayparam.dt0[0]; 0548 /* The main loop */ 0549 while ((t1 < rayparam.tfinal[0]) && (k < kmax)) { 0550 ii++; 0551 /*mexPrintf("ii,k:%d,%d\n",ii,k);*/ 0552 if ((t1 + h) > rayparam.tfinal[0]) { 0553 h = rayparam.tfinal[0] - t1; 0554 } 0555 if (ii > iimax) { 0556 mexPrintf("iimax is reached"); 0557 goto Endloop; 0558 flag1 = 2; 0559 } 0560 /*mexPrintf("S1:%g\n",S1);*/ 0561 0562 /* 0563 ############################################## 0564 Redifinition of the metric system if necessary 0565 ############################################## 0566 */ 0567 0568 /*------------------------- Switching condition set around rho = 0.1 -----------------------------------*/ 0569 if((int)rayparam.metricmode[0] == 2) 0570 { 0571 0572 if (flag_metric == 1 && rho1 < rayparam.rhoswitch[0]*(1 - rayparam.deltaswitch[0])) 0573 { 0574 mexPrintf("%s \n","Switching on cartesian system"); 0575 rhotheta2xy(rayparam,rayequil,equilparam,&rho1,&theta1,&krho1,&m1); 0576 mexPrintf("%s = %d\n", "Total number of saved iterations", k); 0577 mexPrintf("%s = %d\n", "Total number of iterations", ii); 0578 flag_metric = 2; 0579 } 0580 0581 if (flag_metric == 2) 0582 { 0583 double rho,theta,t[2]; 0584 t[0]=rho1; 0585 t[1]=theta1; 0586 substitution(rayequil,rayparam,equilparam,&rho,&theta,&t); 0587 if(rho > rayparam.rhoswitch[0]*(1 + rayparam.deltaswitch[0])) 0588 { 0589 mexPrintf("%s \n","Switching off cartesian system"); 0590 xy2rhotheta(rayparam,rayequil,equilparam,&rho1,&theta1,&krho1,&m1); 0591 mexPrintf("%s = %d\n", "Total number of saved iterations", k); 0592 mexPrintf("%s = %d\n", "Total number of iterations", ii); 0593 flag_metric = 1; 0594 } 0595 } 0596 0597 } 0598 0599 /*------------------------------------------------------------------------------------------------------*/ 0600 0601 if (k == -1 || fabs(S1 - S_step) >= rayparam.dS[0]){/*step stored in Matlab memory */ 0602 0603 k++; 0604 0605 if(flag_metric == 2)/*Reset to flux coordinates for saveguard purposes if in cartesian coordinates*/ 0606 { 0607 xy2rhotheta(rayparam,rayequil,equilparam,&rho1,&theta1,&krho1,&m1); 0608 } 0609 0610 tempt[k] = t1; 0611 temp0[k] = rho1; 0612 temp1[k] = theta1; 0613 temp2[k] = z1; 0614 temp3[k] = krho1; 0615 temp4[k] = m1; 0616 temp5[k] = kz1; 0617 temp6[k] = omega1; 0618 temp7[k] = S1; 0619 0620 if(flag_metric == 2)/*Reset to cartesian coordinates for raytracing calculations if initially in cartesian coordinates*/ 0621 { 0622 rhotheta2xy(rayparam,rayequil,equilparam,&rho1,&theta1,&krho1,&m1); 0623 } 0624 0625 if (flag_proc == 1) { /* calculate additional ray parameters if required */ 0626 0627 dS = S1 - S_step; /* ray path from k-1 to k position */ 0628 /*y0 needs to be expressed in the current metric system*/ 0629 y0[0] = rho1; 0630 y0[1] = theta1; 0631 y0[2] = temp2[k]; 0632 y0[3] = krho1; 0633 y0[4] = m1; 0634 y0[5] = temp5[k]; 0635 y0[6] = temp6[k]; 0636 0637 if (equilparam.zZi[0] > 0) {/*no absorption in vacuum*/ 0638 0639 rayprocess(ns,rayproc,rayparam,raymagnetic,rayprofiles,X,equilparam,fluctparam,yinit,y0,rayequil,rayfluctuations,distriparam,raydistri,flag_f0,flag,flag_fluct,flag_metric); 0640 /* mexPrintf("y[0],y[1],y[2],y[3],y[4],y[5],y[6]:%g,%g,%g,%g,%g,%g,%g\n",yinit[0],yinit[1],yinit[2],yinit[3],yinit[4],yinit[5],yinit[6]);*/ 0641 /* mexPrintf("y[0],y[1],y[2],y[3],y[4],y[5],y[6]:%g,%g,%g,%g,%g,%g,%g\n",yinit[0],yinit[1],yinit[2],yinit[3],yinit[4],yinit[5],yinit[6]); */ 0642 /*return;*/ 0643 /* Stop here for debug and uncomment the calculation of Dtot which should be very close to zero*/ 0644 0645 0646 for (i=0;i /* absphi = sqrt(fabs(phix2) + fabs(phiy2) + fabs(phiz2)); */ 0651 absphi = sqrt(fabs(rayproc[9]*rayproc[9]) + fabs(rayproc[10]*rayproc[10]) + fabs(rayproc[11]*rayproc[11])); 0652 0653 /* alpha = alphaphi*equilparam.ap[0]*y0[6]/CLUM/absphi; */ 0654 alpha2 = rayproc[12]*equilparam.ap[0]*y0[6]/CLUM/absphi; 0655 0656 /* Optical depth */ 0657 0658 depth = depth + (alpha1 + alpha2)*dS/2; 0659 0660 /* 0661 if (fmod(k,200) == 0) { 0662 mexPrintf("t,k,rho,tau:%g,%d,%g,%g\n",t1,k,y0[0],depth); 0663 } */ 0664 0665 temp_proc[MPROC+2*ns][k] = depth; 0666 0667 0668 if (tau_lim > 0.0 && depth > tau_lim) { /* The power is fully absorbed. */ 0669 mexPrintf("The wave is fully linearly damped at k = %i\n",k); 0670 0671 kmax = (int)fmin((double)kmax,(double)k + rayparam.kextra[0]); 0672 0673 mexPrintf("----> Calculation stopped at k = %i\n",kmax); 0674 tau_lim = 0.0; 0675 0676 } 0677 0678 alpha1 = alpha2; 0679 } 0680 } 0681 0682 S_step = S1; 0683 } 0684 /* 0685 Compute the slopes 0686 */ 0687 0688 /* ts = t and s0 = y */ 0689 0690 0691 s0[0] = rho1; 0692 s0[1] = theta1; 0693 s0[2] = z1; 0694 s0[3] = krho1; 0695 s0[4] = m1; 0696 s0[5] = kz1; 0697 s0[6] = omega1; 0698 0699 for (m = 0; m < MC; m++) { 0700 y1[m] = s0[m]; 0701 } 0702 0703 ray(ns,X,s1,&Sdot1,yinit,y1,raymagnetic,rayprofiles,rayparam,equilparam,fluctparam,rayequil,rayfluctuations,flag,flag_fluct,flag_metric); 0704 /* s2 = feval(F, t+h*alpha(1), y1+h*s1*beta(1,1), param); */ 0705 0706 0707 for (m = 0; m < MC-2; m++) {/* only the first six coordinates are evolving (rho,theta,phi,krho,m,n) */ 0708 y1[m] = s0[m]+h*s1[m]*beta[0][0]; 0709 } 0710 0711 0712 ray(ns,X,s2,&Sdot2,yinit,y1,raymagnetic,rayprofiles,rayparam,equilparam,fluctparam,rayequil,rayfluctuations,flag,flag_fluct,flag_metric); 0713 /* s3 = feval(F, t+h*alpha(2), y1+h*[s1*beta(2,1)+s2*beta(2,2)], param); */ 0714 0715 for (m = 0; m < MC-2; m++) { 0716 y1[m] = s0[m]+h*(s1[m]*beta[0][1] + s2[m]*beta[1][1]); 0717 } 0718 0719 ray(ns,X,s3,&Sdot3,yinit,y1,raymagnetic,rayprofiles,rayparam,equilparam,fluctparam,rayequil,rayfluctuations,flag,flag_fluct,flag_metric); 0720 0721 /* s4 = feval(F, t+h*alpha(3), y1+h*[s1*beta(3,1)+s2*beta(3,2)+...], param); */ 0722 0723 for (m = 0; m < MC-2; m++) { 0724 y1[m] = s0[m]+h*(s1[m]*beta[0][2] + s2[m]*beta[1][2] + s3[m]*beta[2][2]); 0725 } 0726 0727 ray(ns,X,s4,&Sdot4,yinit,y1,raymagnetic,rayprofiles,rayparam,equilparam,fluctparam,rayequil,rayfluctuations,flag,flag_fluct,flag_metric); 0728 0729 /* s5 = feval(F, t+h*alpha(4), y1+h*[s1*beta(4,1)+s2*beta(4,2)+...], param); */ 0730 0731 for (m = 0; m < MC-2; m++) { 0732 y1[m] = s0[m]+h*(s1[m]*beta[0][3] + s2[m]*beta[1][3] + s3[m]*beta[2][3] + s4[m]*beta[3][3]); 0733 } 0734 0735 0736 ray(ns,X,s5,&Sdot5,yinit,y1,raymagnetic,rayprofiles,rayparam,equilparam,fluctparam,rayequil,rayfluctuations,flag,flag_fluct,flag_metric); 0737 0738 /* s6 = feval(F, t+h*alpha(5), y1+h*[s1*beta(5,1)+s2*beta(5,2)+...], param); */ 0739 0740 for (m = 0; m < MC-2; m++) { 0741 y1[m] = s0[m]+h*(s1[m]*beta[0][4] + s2[m]*beta[1][4] + s3[m]*beta[2][4] + s4[m]*beta[3][4] + s5[m]*beta[4][4]); 0742 } 0743 0744 ray(ns,X,s6,&Sdot6,yinit,y1,raymagnetic,rayprofiles,rayparam,equilparam,fluctparam,rayequil,rayfluctuations,flag,flag_fluct,flag_metric); 0745 0746 /* 0747 Estimate the error and the acceptable error 0748 */ 0749 0750 for (m = 0; m < MC; m++) { 0751 ydel[m] = h*(s1[m]*gama[0][1] + s2[m]*gama[1][1] + s3[m]*gama[2][1] + s4[m]*gama[3][1] + s5[m]*gama[4][1] + s6[m]*gama[5][1]); 0752 ys[0] = s0[m]; 0753 ys[1] = s1[m]; 0754 ys[2] = s2[m]; 0755 ys[3] = s3[m]; 0756 ys[4] = s4[m]; 0757 ys[5] = s5[m]; 0758 ys[6] = s6[m]; 0759 0760 /* mexPrintf("m,s0[m],s1[m],s2[m],s3[m],s4[m],s5[m],s6[m]:%d,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g\n",m,s0[m],s1[m],s2[m],s3[m],s4[m],s5[m],s6[m]); */ 0761 0762 0763 ymax = inf_norm(ys,MC-1); 0764 ydel[m] = ydel[m]/ymax; 0765 0766 /* mexPrintf("ys[0],ys[1],ys[2],ys[3],ys[4],ys[5],ys[6],ymax,ydel[m]:%g,%g,%g,%g,%g,%g,%g,%g,%g\n",ys[0],ys[1],ys[2],ys[3],ys[4],ys[5],ys[6],ymax,ydel[m]); */ 0767 0768 } 0769 0770 0771 /* mexPrintf("ydel[0],ydel[1],ydel[2],ydel[3],ydel[4],ydel[5],ydel[6]:%g,%g,%g,%g,%g,%g,%g\n",ydel[0],ydel[1],ydel[2],ydel[3],ydel[4],ydel[5],ydel[6]); */ 0772 0773 delta = inf_norm(ydel,MC-2);/* only the first six coordinates are evolving (rho,theta,phi,krho,m,n) */ 0774 tau = rayparam.tol[0]; 0775 0776 /* 0777 Update the solution only if the error is acceptable 0778 */ 0779 0780 /*mexPrintf("k,kmax,t1,delta,ymax,h,rho1,theta1,z1,krho1,m1,kz1:%d,%d,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g\n",k,kmax,t1,delta,ymax,h,rho1,theta1,z1,krho1,m1,kz1);*/ 0781 0782 0783 if (delta <= tau) { 0784 t2 = t1 + h; 0785 0786 rhodot = s1[0]*gama[0][0] + s2[0]*gama[1][0] + s3[0]*gama[2][0] + s4[0]*gama[3][0] + s5[0]*gama[4][0] + s6[0]*gama[5][0]; 0787 thetadot = s1[1]*gama[0][0] + s2[1]*gama[1][0] + s3[1]*gama[2][0] + s4[1]*gama[3][0] + s5[1]*gama[4][0] + s6[1]*gama[5][0]; 0788 zdot = s1[2]*gama[0][0] + s2[2]*gama[1][0] + s3[2]*gama[2][0] + s4[2]*gama[3][0] + s5[2]*gama[4][0] + s6[2]*gama[5][0]; 0789 krhodot = s1[3]*gama[0][0] + s2[3]*gama[1][0] + s3[3]*gama[2][0] + s4[3]*gama[3][0] + s5[3]*gama[4][0] + s6[3]*gama[5][0]; 0790 mdot = s1[4]*gama[0][0] + s2[4]*gama[1][0] + s3[4]*gama[2][0] + s4[4]*gama[3][0] + s5[4]*gama[4][0] + s6[4]*gama[5][0]; 0791 kzdot = s1[5]*gama[0][0] + s2[5]*gama[1][0] + s3[5]*gama[2][0] + s4[5]*gama[3][0] + s5[5]*gama[4][0] + s6[5]*gama[5][0]; 0792 omegadot = 0.0; 0793 0794 Sdot = Sdot1*gama[0][0] + Sdot2*gama[1][0] + Sdot3*gama[2][0] + Sdot4*gama[3][0] + Sdot5*gama[4][0] + Sdot6*gama[5][0]; 0795 0796 rho2 = rho1 + h*rhodot; 0797 theta2 = theta1 + h*thetadot; 0798 z2 = z1 + h*zdot; 0799 krho2 = krho1 + h*krhodot; 0800 m2 = m1 + h*mdot; 0801 kz2 = kz1 + h*kzdot; 0802 omega2 = omega1 + h*omegadot; 0803 S2 = S1 + h*Sdot; 0804 0805 /* mexPrintf("t2,rho2,theta2,z2,krho2,m2,kz2:%g,%g,%g,%g,%g,%g,%g\n",t2,rho2,theta2,z2,krho2,m2,kz2);*/ 0806 0807 if(flag_metric==1)/*In order that the condition rho2 > 1.0 is always false in cartesian metric*/ 0808 { 0809 if (rho2 > 1.0) {/* Wave reflexion at rho = 1 */ 0810 if (rayparam.reflection[0] >=1.0) {/* The reflection is always enforced */ 0811 mexPrintf("********************************** Wave reflection is enforced at rho = %g**********************************\n",rho1); 0812 rho2 = rho1; 0813 z2 = z1; 0814 theta2 = theta1; 0815 omega2 = omega1; 0816 /* S2 = S1; */ 0817 0818 if (reflection(flag,X,rayparam,equilparam,fluctparam,raymagnetic,rayprofiles,&krho2,&m2,&kz2,yinit,s0,rayequil,rayfluctuations,flag_fluct) == -1) {goto Endloop;} 0819 } else {/* The code calculates if the reflection must takes place. It calculates kpsi for vacuum (keeping the magnetic field) ray leaves the plasma only if kspi is real.*/ 0820 s0[0] = rho1; 0821 s0[1] = theta1; 0822 s0[2] = z1; 0823 s0[3] = krho1; 0824 s0[4] = m1; 0825 s0[5] = kz1; 0826 s0[6] = omega1; 0827 dsolve(0,ns,&krho2,yinit,s0,raymagnetic,rayprofiles,X,rayparam,equilparam,fluctparam,rayequil,rayfluctuations,flag,flag_fluct); 0828 /* mexPrintf("test2a,krho2,cimag(krho2):%g,%g,%g\n",krho2,cimag(krho2));*/ 0829 if (cimag(krho2) == 0.0) {/* ray may propagate in vacuum. Propagation is stopped */ 0830 mexPrintf("********************************** The wave leaves the plasma at rho = %g**********************************\n",rho1); 0831 flag1 = 1; 0832 goto Endloop; 0833 } else {/* ray may not propagate in vacuum. Wave reflection is performed at plasma edge */ 0834 mexPrintf("********************************** Wave reflection takes place at rho = %g**********************************\n",rho1); 0835 rho2 = rho1; 0836 z2 = z1; 0837 theta2 = theta1; 0838 if (reflection(flag,X,rayparam,equilparam,fluctparam,raymagnetic,rayprofiles,&krho2,&m2,&kz2,yinit,s0,rayequil,rayfluctuations,flag_fluct) == -1) {goto Endloop;} 0839 } 0840 } 0841 } 0842 0843 } 0844 0845 t1 = t2; 0846 rho1 = rho2; 0847 theta1 = theta2; 0848 z1 = z2; 0849 krho1 = krho2; 0850 m1 = m2; 0851 kz1 = kz2; 0852 omega1 = omega2; 0853 0854 S1 = S2; 0855 0856 } 0857 0858 /* 0859 Update the step size 0860 */ 0861 0862 if (delta) { 0863 if (delta < tau) { 0864 h = SAFETY*h*pow(tau/delta,PGROW); 0865 } else { 0866 h = SAFETY*h*pow(tau/delta,PSHRINK); 0867 } 0868 0869 0870 /* mexPrintf("k,delta,tau,rho1,krho1,S1,h:%d,%g,%g,%g,%g,%g,%g\n",k,delta,tau,rho1,krho1,S1,h); */ 0871 0872 } else { 0873 mexPrintf("WARNING delta :%g, the loop is stopped.\n",delta); 0874 if (flag1 == 0) { 0875 mexPrintf("---> The maximum number of iteration is reached.\n",delta); 0876 } 0877 if (flag1 == 1) { 0878 mexPrintf("---> The ray leaves the plasma.\n",delta); 0879 } 0880 if (flag1 == 2) { 0881 mexPrintf("WARNING: the code has reached a stationary point. Exit forced at %i steps.\n",iimax); 0882 } 0883 if (flag1 == 3) { 0884 mexPrintf("WARNING: The distance of the ray to the magnetic axis is less than the minimal distance. Exit enforced.\n",delta); 0885 } 0886 goto Endloop; 0887 } 0888 0889 } 0890 0891 /* if (t1 < rayparam.tfinal[0]) { 0892 mexPrintf("Singularity likely at t = %f or matrix full\n",t1); 0893 }*/ 0894 0895 Endloop: 0896 0897 mexPrintf("%d \n",k); 0898 mexPrintf("%d \n",ii); 0899 0900 /* Create final matrix for transferring data to MatLab */ 0901 0902 T_OUT = mxCreateDoubleMatrix(k,1,mxREAL); 0903 Y_OUT = mxCreateDoubleMatrix(k,MC,mxREAL); 0904 tout = mxGetPr(T_OUT); 0905 yout = mxGetPr(Y_OUT); 0906 0907 for (kk = 0;kk < k; kk++) { 0908 tout[kk] = tempt[kk]; 0909 } 0910 for (kk = 0;kk < k; kk++) { 0911 yout[kk] = temp0[kk]; 0912 } 0913 for (kk = 0;kk < k; kk++) { 0914 yout[kk + k] = temp1[kk]; 0915 } 0916 for (kk = 0;kk < k; kk++) { 0917 yout[kk + 2*k] = temp2[kk]; 0918 } 0919 for (kk = 0;kk < k; kk++) { 0920 yout[kk + 3*k] = temp3[kk]; 0921 } 0922 for (kk = 0;kk < k; kk++) { 0923 yout[kk + 4*k] = temp4[kk]; 0924 } 0925 for (kk = 0;kk < k; kk++) { 0926 yout[kk + 5*k] = temp5[kk]; 0927 } 0928 for (kk = 0;kk < k; kk++) { 0929 yout[kk + 6*k] = temp6[kk]; 0930 } 0931 for (kk = 0;kk < k; kk++) { 0932 yout[kk + 7*k] = temp7[kk]; 0933 } 0934 0935 /* Memory is released */ 0936 0937 if (flag != 0) { 0938 mxFree(equilparam.zZi); 0939 mxFree(equilparam.zmi); 0940 mxFree(equilparam.ns); 0941 mxFree(equilparam.Rp); 0942 mxFree(equilparam.ap); 0943 mxFree(equilparam.Zp); 0944 mxFree(equilparam.psia_apRp); 0945 } 0946 0947 mxFree(raymagnetic.rn); 0948 mxFree(raymagnetic.xn); 0949 mxFree(raymagnetic.yn); 0950 mxFree(raymagnetic.Brhon); 0951 mxFree(raymagnetic.Bsn); 0952 mxFree(raymagnetic.Bzn); 0953 mxFree(raymagnetic.B); 0954 mxFree(raymagnetic.salpha); 0955 mxFree(raymagnetic.calpha); 0956 mxFree(raymagnetic.gradrhon); 0957 mxFree(raymagnetic.rhorip); 0958 mxFree(raymagnetic.Upsilonn); 0959 0960 mxFree(raymagnetic.drndY); 0961 mxFree(raymagnetic.dxndY); 0962 mxFree(raymagnetic.dyndY); 0963 mxFree(raymagnetic.dBrhondY); 0964 mxFree(raymagnetic.dBsndY); 0965 mxFree(raymagnetic.dBzndY); 0966 mxFree(raymagnetic.dBdY); 0967 mxFree(raymagnetic.dsalphadY); 0968 mxFree(raymagnetic.dcalphadY); 0969 mxFree(raymagnetic.dgradrhondY); 0970 mxFree(raymagnetic.drhoripdY); 0971 mxFree(raymagnetic.dUpsilonndY); 0972 0973 mxFree(raymagnetic.d2rndY2); 0974 mxFree(raymagnetic.d2xndY2); 0975 mxFree(raymagnetic.d2yndY2); 0976 mxFree(raymagnetic.d2BrhondY2); 0977 mxFree(raymagnetic.d2BsndY2); 0978 mxFree(raymagnetic.d2BzndY2); 0979 mxFree(raymagnetic.d2BdY2); 0980 mxFree(raymagnetic.d2salphadY2); 0981 mxFree(raymagnetic.d2calphadY2); 0982 mxFree(raymagnetic.d2gradrhondY2); 0983 mxFree(raymagnetic.d2rhoripdY2); 0984 mxFree(raymagnetic.d2UpsilonndY2); 0985 0986 0987 mxFree(rayprofiles.Te); 0988 mxFree(rayprofiles.ne); 0989 mxFree(rayprofiles.zTi); 0990 mxFree(rayprofiles.zni); 0991 0992 mxFree(rayprofiles.dTedY); 0993 mxFree(rayprofiles.dnedY); 0994 0995 mxFree(rayprofiles.d2TedY2); 0996 mxFree(rayprofiles.d2nedY2); 0997 0998 for (i = 0;i < ns; i++) { 0999 mxFree(rayprofiles.dzTidY[i]); 1000 mxFree(rayprofiles.dznidY[i]); 1001 mxFree(rayprofiles.d2zTidY2[i]); 1002 mxFree(rayprofiles.d2znidY2[i]); 1003 } 1004 1005 mxFree(rayprofiles.dzTidY); 1006 mxFree(rayprofiles.dznidY); 1007 mxFree(rayprofiles.d2zTidY2); 1008 mxFree(rayprofiles.d2znidY2); 1009 1010 mxFree(X.Xxx); 1011 mxFree(X.Xxy); 1012 mxFree(X.Xxz); 1013 mxFree(X.Xyy); 1014 mxFree(X.Xyz); 1015 mxFree(X.Xzz); 1016 1017 mxFree(X.dXxxdNperp); 1018 mxFree(X.dXxydNperp); 1019 mxFree(X.dXxzdNperp); 1020 mxFree(X.dXyydNperp); 1021 mxFree(X.dXyzdNperp); 1022 mxFree(X.dXzzdNperp); 1023 1024 mxFree(X.dXxxdNpar); 1025 mxFree(X.dXxydNpar); 1026 mxFree(X.dXxzdNpar); 1027 mxFree(X.dXyydNpar); 1028 mxFree(X.dXyzdNpar); 1029 mxFree(X.dXzzdNpar); 1030 1031 mxFree(X.dXxxdY); 1032 mxFree(X.dXxydY); 1033 mxFree(X.dXxzdY); 1034 mxFree(X.dXyydY); 1035 mxFree(X.dXyzdY); 1036 mxFree(X.dXzzdY); 1037 1038 mxFree(tempt); 1039 mxFree(temp0); 1040 mxFree(temp1); 1041 mxFree(temp2); 1042 mxFree(temp3); 1043 mxFree(temp4); 1044 mxFree(temp5); 1045 mxFree(temp6); 1046 mxFree(temp7); 1047 1048 mxFree(y0); 1049 mxFree(y0dot); 1050 mxFree(y1); 1051 mxFree(s0); 1052 mxFree(s1); 1053 mxFree(s2); 1054 mxFree(s3); 1055 mxFree(s4); 1056 mxFree(s5); 1057 mxFree(s6); 1058 1059 if (flag_proc == 1) { 1060 1061 if (equilparam.zZi[0]>0) { 1062 1063 Y_PROC = mxCreateDoubleMatrix(k,MPROC+2*ns+1,mxREAL); 1064 yproc = mxGetPr(Y_PROC); 1065 1066 for (kk = 0;kk < k; kk++) { 1067 for (i=0;i /* Memory is released */ 1073 1074 for (i=0;i else { 1082 1083 Y_PROC = mxCreateDoubleMatrix(1,1,mxREAL); 1084 yproc = mxGetPr(Y_PROC); 1085 yproc[1] = 0.0; 1086 } 1087 1088 } 1089 1090 if (flag_fluct == 1) { 1091 1092 if (fluctparam.ne_nmodel[0]) { 1093 1094 } 1095 1096 if (fluctparam.B_nmodel[0]) { 1097 1098 mxFree(rayfluctuations.B_sfx_fit); 1099 mxFree(rayfluctuations.B_sfy_fit); 1100 mxFree(rayfluctuations.B_sfz_fit); 1101 1102 } 1103 1104 } else { 1105 1106 mxFree(fluctparam.ne_nmodel); 1107 mxFree(fluctparam.B_nmodel); 1108 } 1109 1110 /* End of C3PO */ 1111 } 1112 1113 1114 1115 1116 double inf_norm(y,N) 1117 double y[]; 1118 unsigned int N; 1119 { 1120 register unsigned int m; 1121 double temp_max; 1122 1123 temp_max = fabs(y[0]); 1124 1125 for (m = 1; m < N; m++) { 1126 temp_max = fmax(temp_max,fabs(y[m])); 1127 } 1128 1129 return(temp_max); 1130 } 1131 1132 1133 /* General coordinate time evolution dY/dt with Y=[rho,theta,phi,krho,m,n,omega/c] */ 1134 1135 1136 void ray(ns,X,Ydot,Sdot,Y0,Y,raymagnetic,rayprofiles,rayparam,equilparam,fluctparam,rayequil,rayfluctuations,flag,flag_fluct,flag_metric)/*Doesn't have to be modified under a change of metric*/ 1137 int ns; 1138 susceptibilitytensor_format X; 1139 double Y0[],Y[],Ydot[],*Sdot; 1140 raymagnetic_format raymagnetic; 1141 rayprofiles_format rayprofiles; 1142 rayparam_format rayparam; 1143 equilparam_format equilparam; 1144 fluctparam_format fluctparam; 1145 rayequil_format rayequil; 1146 rayfluctuations_format rayfluctuations; 1147 double flag; 1148 int flag_fluct; 1149 int flag_metric; 1150 { 1151 1152 register int i,j; 1153 1154 double Npar,dNpardY[MC]; 1155 double complex Dtot,dDtotdY[MC]; 1156 double complex Nperp,dNperpdY[MC],N2,dN2dY[MC],eikval; 1157 1158 double Sdot2; 1159 double Gcov[3][3]; 1160 double wcn[ns+1],wpn2[ns+1],betath[ns+1]; 1161 1162 1163 /* Equilibrium interpolation at ray location */ 1164 if (flag == 0) { 1165 interpequil(rayparam,raymagnetic,rayprofiles,equilparam,fluctparam,Y0,Y,rayequil,rayfluctuations,flag_fluct,flag_metric); 1166 } else { 1167 interpequil_test(raymagnetic,rayprofiles,equilparam,Y,flag); 1168 } 1169 1170 /* Refractive index calculation */ 1171 rayindex(&Nperp,dNperpdY,&N2,dN2dY,flag_metric,Y,raymagnetic,equilparam,&Npar,dNpardY,&eikval); 1172 1173 /* 1174 mexPrintf("rn,xn,yn,Brhon,Bsn,krho,sina,cosa,B,Bzn:%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g\n",raymagnetic.rn[0],raymagnetic.xn[0],raymagnetic.yn[0],raymagnetic.Brhon[0],raymagnetic.Bsn[0],Y[3],raymagnetic.salpha[0],raymagnetic.calpha[0],raymagnetic.B[0],raymagnetic.Bzn[0]); 1175 mexPrintf("Npar,w*dNpardw,Nperpr,Nperpi,w*dNperpdwr,w*dNperpdwi:%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g\n",Npar,dNpardY[6],Nperp,dNperpdY[6]); 1176 */ 1177 1178 /*mexPrintf("Eikonal validity (<< 1):%g,%g\n",eikval);*/ 1179 1180 1181 /* Susceptibility tensor */ 1182 1183 susceptibility(X,Nperp,dNperpdY,wcn,wpn2,betath,rayparam.tensortype[0],(int)rayparam.ncyclharm[0],equilparam,raymagnetic,rayprofiles,Npar,dNpardY,Y[6]); 1184 1185 /* mexPrintf("X.Xxx[0],X.Xxy[0],X.Xxz[0],X.Xyy[0],X.Xyz[0],X.Xzz[0],%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g\n",X.Xxx[0],X.Xxy[0],X.Xxz[0],X.Xyy[0],X.Xyz[0],X.Xzz[0]); */ 1186 1187 if (flag < 0) {/* dispersion relation */ 1188 disprel(dDtotdY,&Dtot,X,dNperpdY,Nperp,dN2dY,N2,dNpardY,Npar,3); 1189 } else { 1190 disprel(dDtotdY,&Dtot,X,dNperpdY,Nperp,dN2dY,N2,dNpardY,Npar,1); 1191 } 1192 1193 if (equilparam.zZi[0] > 0) { 1194 Ydot[0] = -creal(dDtotdY[3])/creal(dDtotdY[6]); 1195 Ydot[1] = -creal(dDtotdY[4])/creal(dDtotdY[6]); 1196 Ydot[2] = -creal(dDtotdY[5])/creal(dDtotdY[6]); 1197 Ydot[3] = creal(dDtotdY[0])/creal(dDtotdY[6]); 1198 Ydot[4] = creal(dDtotdY[1])/creal(dDtotdY[6]); 1199 Ydot[5] = creal(dDtotdY[2])/creal(dDtotdY[6]); 1200 Ydot[6] = 0.0; 1201 } else {/* vacuum case */ 1202 Ydot[0] = -creal(dN2dY[3])/creal(dN2dY[6]); 1203 Ydot[1] = -creal(dN2dY[4])/creal(dN2dY[6]); 1204 Ydot[2] = -creal(dN2dY[5])/creal(dN2dY[6]); 1205 Ydot[3] = creal(dN2dY[0])/creal(dN2dY[6]); 1206 Ydot[4] = creal(dN2dY[1])/creal(dN2dY[6]); 1207 Ydot[5] = creal(dN2dY[2])/creal(dN2dY[6]); 1208 Ydot[6] = 0.0; 1209 } 1210 /* Calculation of the infinitesimal path length */ 1211 1212 metrictensor(Gcov,raymagnetic,flag_metric); 1213 1214 Sdot2 = 0.0; 1215 1216 for (i=0;i<3;i++) { 1217 for (j=0;j<3;j++) { 1218 Sdot2 = Sdot2 + Gcov[i][j]*Ydot[i]*Ydot[j]; 1219 } 1220 } 1221 1222 Sdot[0] = sqrt(Sdot2); 1223 1224 /* test for the cold dispersion relation */ 1225 /* 1226 double complex P0,P2,P4,dP0dY[MC],dP2dY[MC],dP4dY[MC]; 1227 double complex Kpar,Kperp,Kxy,dKpardY[MC],dKperpdY[MC],dKxydY[MC]; 1228 double complex Dot_cold,dDtot_colddY[MC]; 1229 double Ydot_cold[MC]; 1230 1231 Kpar = (1 + Xzz)/N2; 1232 Kperp = (1 + Xxx)/N2; 1233 Kxy = I*Xxy/N2; 1234 1235 P0 = Kpar*((Npar2/N2 - Kperp)*(Npar2/N2 - Kperp) - Kxy*Kxy); 1236 P2 = (Npar2/N2 - Kperp)*(Kpar + Kperp) + Kxy*Kxy; 1237 P4 = Kperp; 1238 1239 Dot_cold = P4*Nperp4/N2/N2 + P2*Nperp2/N2 + P0; 1240 mexPrintf("Dtot_cold:%g,%g\n",Dot_cold); 1241 1242 for (i=0;i<MC;i++) { 1243 dKpardY[i] = X.dXzzdY[i]/N2 - (1+Xzz)*dN2dY[i]/N2/N2; 1244 dKperpdY[i] = X.dXxxdY[i]/N2 - (1+Xxx)*dN2dY[i]/N2/N2; 1245 dKxydY[i] = I*X.dXxydY[i]/N2 - I*Xxy*dN2dY[i]/N2/N2; 1246 dP0dY[i] = dKpardY[i]*((Npar2/N2 - Kperp)*(Npar2/N2 - Kperp) - Kxy*Kxy) + Kpar*(2*(Npar2/N2 - Kperp)*(2*Npar1*dNpardY[i]/N2 - Npar2*dN2dY[i]/N2/N2 - dKperpdY[i]) - 2*Kxy*dKxydY[i]); 1247 dP2dY[i] = (2*Npar1*dNpardY[i]/N2 - Npar2*dN2dY[i]/N2/N2 - dKperpdY[i])*(Kpar + Kperp) + (Npar2/N2 - Kperp)*(dKpardY[i] + dKperpdY[i]) + 2*Kxy*dKxydY[i]; 1248 dP4dY[i] = dKperpdY[i]; 1249 dDtot_colddY[i] = dP4dY[i]*Nperp4/N2/N2 + dP2dY[i]*Nperp2/N2 + dP0dY[i] + P4*(4*Nperp3*dNperpdY[i]/N2/N2 - 2*Nperp4*dN2dY[i]/N2/N2/N2) + P2*(2*Nperp*dNperpdY[i]/N2 - Nperp2*dN2dY[i]/N2/N2); 1250 } 1251 1252 Ydot[0] = -creal(dDtot_colddY[3])/creal(dDtot_colddY[6]); 1253 Ydot[1] = -creal(dDtot_colddY[4])/creal(dDtot_colddY[6]); 1254 Ydot[2] = -creal(dDtot_colddY[5])/creal(dDtot_colddY[6]); 1255 Ydot[3] = creal(dDtot_colddY[0])/creal(dDtot_colddY[6]); 1256 Ydot[4] = creal(dDtot_colddY[1])/creal(dDtot_colddY[6]); 1257 Ydot[5] = 0.0; 1258 Ydot[6] = 0.0; 1259 */ 1260 1261 /* 1262 1263 mexPrintf("dN2dY[1]:%g\n",dN2dY[1]); 1264 mexPrintf("dDtotdY:%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g\n",dDtotdY[0],dDtotdY[1],dDtotdY[2],dDtotdY[3],dDtotdY[4],dDtotdY[5],dDtotdY[6],dDtotdY[7]); 1265 mexPrintf("dDtot_colddY:%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g\n",dDtot_colddY[0],dDtot_colddY[1],dDtot_colddY[2],dDtot_colddY[3],dDtot_colddY[4],dDtot_colddY[5],dDtot_colddY[6]); 1266 mexPrintf("Ydot:%g,%g,%g,%g,%g,%g,%g,%g\n",Ydot[0],Ydot[1],Ydot[2],Ydot[3],Ydot[4],Ydot[5],Ydot[6],Ydot[7]); 1267 mexPrintf("Ydot_cold:%g,%g,%g,%g,%g,%g,%g\n",Ydot_cold[0],Ydot_cold[1],Ydot_cold[2],Ydot_cold[3],Ydot_cold[4],Ydot_cold[5],Ydot_cold[6]); 1268 1269 */ 1270 1271 } 1272 1273 void metrictensor(Gcov,raymagnetic,flag_metric)/*Has to be modified under a change of metric*/ 1274 double Gcov[3][3]; 1275 raymagnetic_format raymagnetic; 1276 int flag_metric; 1277 { 1278 if (flag_metric == 1)/*Flux case*/ 1279 { 1280 Gcov[0][0] = 1/raymagnetic.gradrhon[0]/raymagnetic.gradrhon[0]/raymagnetic.calpha[0]/raymagnetic.calpha[0]; 1281 Gcov[0][1] = raymagnetic.rn[0]*raymagnetic.salpha[0]/raymagnetic.gradrhon[0]/raymagnetic.calpha[0]/raymagnetic.calpha[0]; 1282 Gcov[0][2] = 0; 1283 Gcov[1][0] = Gcov[0][1]; 1284 Gcov[1][1] = raymagnetic.rn[0]*raymagnetic.rn[0]/raymagnetic.calpha[0]/raymagnetic.calpha[0]; 1285 Gcov[1][2] = 0; 1286 Gcov[2][0] = Gcov[0][2]; 1287 Gcov[2][1] = Gcov[1][2]; 1288 Gcov[2][2] = raymagnetic.Upsilonn[0]*raymagnetic.Upsilonn[0]; 1289 } 1290 else/*Cartesian case*/ 1291 { 1292 Gcov[0][0]=1; 1293 Gcov[0][1]=0; 1294 Gcov[0][2]=0; 1295 Gcov[1][0]=0; 1296 Gcov[1][1]=1; 1297 Gcov[1][2]=0; 1298 Gcov[2][0]=0; 1299 Gcov[2][1]=0; 1300 Gcov[2][2]=raymagnetic.Upsilonn[0]*raymagnetic.Upsilonn[0]; 1301 } 1302 } 1303 1304 1305 void polarization(X,Npar,Nperp,epolx,epoly,epolz,epolp,epolm)/*Doesn't have to be modified under a change of metric*/ 1306 susceptibilitytensor_format X; 1307 double Npar; 1308 double complex Nperp,*epolx,*epoly,*epolz,*epolp,*epolm; 1309 { 1310 double complex a,b,c; 1311 double epolnorm; 1312 1313 a = X.Xxz[0] + Npar*Nperp; 1314 b = Npar*Npar - 1.0 - X.Xxx[0]; 1315 c = Nperp*Nperp - 1.0 - X.Xzz[0]; 1316 1317 /* 1318 epolx[0] = -I*(X.Xxy[0] - X.Xyz[0]*a/c); 1319 epoly[0] = -I*(b - a*a/c); 1320 epolz[0] = (X.Xyz[0]*b - X.Xxy[0]*a)/c; 1321 */ 1322 1323 epolx[0] = I*(X.Xxy[0] - X.Xyz[0]*a/c); 1324 epoly[0] = -I*(b - a*a/c); 1325 epolz[0] = -I*(X.Xyz[0]*b - X.Xxy[0]*a)/c; 1326 1327 epolnorm = sqrt(cabs(epolx[0])*cabs(epolx[0]) + cabs(epoly[0])*cabs(epoly[0]) + cabs(epolz[0])*cabs(epolz[0])); 1328 1329 epolx[0] = epolx[0]/epolnorm; 1330 epoly[0] = epoly[0]/epolnorm; 1331 epolz[0] = epolz[0]/epolnorm; 1332 1333 epolp[0] = (epolx[0] + I*epoly[0])/sqrt(2.0); 1334 epolm[0] = (epolx[0] - I*epoly[0])/sqrt(2.0); 1335 } 1336 1337 1338 void rayprocess(ns,rayproc,rayparam,raymagnetic,rayprofiles,X,equilparam,fluctparam,Y0,Y,rayequil,rayfluctuations,distriparam,raydistri,flag_f0,flag,flag_fluct,flag_metric)/* Has to be modified under a change of metric*/ 1339 int ns; 1340 double rayproc[]; 1341 rayparam_format rayparam; 1342 raymagnetic_format raymagnetic; 1343 rayprofiles_format rayprofiles; 1344 susceptibilitytensor_format X; 1345 equilparam_format equilparam; 1346 fluctparam_format fluctparam; 1347 double Y0[],Y[]; 1348 rayequil_format rayequil; 1349 rayfluctuations_format rayfluctuations; 1350 distriparam_format distriparam; 1351 raydistri_format raydistri; 1352 int flag_f0; 1353 double flag; 1354 int flag_fluct; 1355 int flag_metric; 1356 { 1357 double Npar,Npar2,dNpardY[MC]; 1358 double complex Nperp,dNperpdY[MC]; 1359 double complex N2,dN2dY[MC]; 1360 1361 double complex Dtot,dDtotdY[MC]; 1362 double complex epolx,epoly,epolz,epolp,epolm; 1363 double complex d,eikval; 1364 double alphaphi = 0.0,phix,phiy,phiz,pmin,pmax,yn,yn2; 1365 int n,nmin,nmax,flagn; 1366 register int i; 1367 1368 double wcn[ns+1],wpn2[ns+1],betath[ns+1]; 1369 1370 double *Xf0,*dXf0drho,*d2Xf0drho2; 1371 double *PSI; 1372 double *pn,*mhu; 1373 int npn,nmhu; 1374 double dummy1; 1375 1376 double qe = 1.602176462e-19;/*Absolute value of the electron charge (C) */ 1377 double me = 9.10938188e-31;/*Electron rest mass (Kg) */ 1378 double epsi0 = 8.854187818e-12;/*Free space permittivity (F/m) */ 1379 1380 1381 /* Equilibrium interpolation at ray location */ 1382 if (flag == 0) { 1383 interpequil(rayparam,raymagnetic,rayprofiles,equilparam,fluctparam,Y0,Y,rayequil,rayfluctuations,flag_fluct,flag_metric); 1384 } else { 1385 interpequil_test(raymagnetic,rayprofiles,equilparam,Y,flag); 1386 } 1387 1388 /* Refractive index calculation */ 1389 rayindex(&Nperp,dNperpdY,&N2,dN2dY,flag_metric,Y,raymagnetic,equilparam,&Npar,dNpardY,&eikval); 1390 1391 /* Susceptibility tensor */ 1392 susceptibility(X,Nperp,dNperpdY,wcn,wpn2,betath,rayparam.tensortype[0],(int)rayparam.ncyclharm[0],equilparam,raymagnetic,rayprofiles,Npar,dNpardY,Y[6]); 1393 /* dispersion relation */ 1394 disprel(dDtotdY,&Dtot,X,dNperpdY,Nperp,dN2dY,N2,dNpardY,Npar,2); 1395 1396 /* test mode */ 1397 1398 /* 1399 epolp = 0.7; 1400 epolm = 0.7; 1401 epolz = 0.1; 1402 n = 0; 1403 phix = 0.1; 1404 phiy = 0.0; 1405 phiz = 0.5; 1406 */ 1407 1408 /* polarization vector */ 1409 1410 polarization(X,Npar,Nperp,&epolx,&epoly,&epolz,&epolp,&epolm); 1411 1412 /* energy flow vector */ 1413 1414 /* poynting contribution */ 1415 1416 phix = creal(Nperp); 1417 phiy = 0; 1418 phiz = Npar; 1419 1420 d = conj(epolx)*Nperp + conj(epolz)*Npar; 1421 1422 phix = phix - creal(d*epolx); 1423 phiy = phiy - creal(d*epoly); 1424 phiz = phiz - creal(d*epolz); 1425 1426 /* thermal contribution */ 1427 1428 /*mexPrintf("epolx,epoly,epolz,d:%g+i*%g,%g+i*%g,%g+i*%g,%g+i*%g\n",epolx,epoly,epolz,d); 1429 mexPrintf("creal(Nperp),Npar,-creal(d*epolx),-creal(d*epoly),-creal(d*epolz):%g,%g,%g,%g,%g\n",creal(Nperp),Npar,-creal(d*epolx),-creal(d*epoly),-creal(d*epolz)); 1430 mexPrintf("phiPx,phiPy,phiPz:%g,%g,%g\n",phix,phiy,phiz);*/ 1431 1432 phix = phix - creal(conj(epolx)*X.dXxxdNperp[0]*epolx)/2 1433 - 2*creal(conj(epolx)*X.dXxydNperp[0]*epoly)/2 1434 - 2*creal(conj(epolx)*X.dXxzdNperp[0]*epolz)/2 1435 - creal(conj(epoly)*X.dXyydNperp[0]*epoly)/2 1436 - 2*creal(conj(epoly)*X.dXyzdNperp[0]*epolz)/2 1437 - creal(conj(epolz)*X.dXzzdNperp[0]*epolz)/2; 1438 1439 phiz = phiz - creal(conj(epolx)*X.dXxxdNpar[0]*epolx)/2 1440 - 2*creal(conj(epolx)*X.dXxydNpar[0]*epoly)/2 1441 - 2*creal(conj(epolx)*X.dXxzdNpar[0]*epolz)/2 1442 - creal(conj(epoly)*X.dXyydNpar[0]*epoly)/2 1443 - 2*creal(conj(epoly)*X.dXyzdNpar[0]*epolz)/2 1444 - creal(conj(epolz)*X.dXzzdNpar[0]*epolz)/2; 1445 1446 /*mexPrintf("phiP,phiP,phiP:%g,%g,%g\n",phix,phiy,phiz);*/ 1447 1448 /*mexPrintf("wpn2,wcn,betath,Npar,Nperp,epolp,epolm,epolz,n,rel_opt,nperp,pperpmax:%g,%g,%g,%g,%g,%g,%g,%g,%i,%i,%i,%g\n",wpn2[0],wcn[0],betath[0],Npar,creal(Nperp),epolp,epolm,epolz,n,(int)rayparam.rel_opt[0],(int)rayparam.nperp[0],rayparam.pperpmax[0]);*/ 1449 1450 /* harmonics to be considered */ 1451 1452 flagn = 0; 1453 Npar2 = Npar*Npar; 1454 pmax = rayparam.pperpmax[0]; 1455 1456 if (Npar2 > 1 && betath[0]*pmax*sqrt(Npar2 - 1) > 1) { 1457 nmin = 0; /* Landau damping is significant */ 1458 } else { 1459 nmin = 1; /* Only cyclotron damping is significant */ 1460 } 1461 1462 nmax = 0; 1463 1464 while (flagn == 0) { 1465 nmax = nmax + 1; 1466 1467 yn = -wcn[0]*nmax; 1468 yn2 = yn*yn; 1469 1470 /* Minimum of p on resonance curves */ 1471 1472 if (Npar2 > 1) { 1473 pmin = fabs(sqrt(yn2 + Npar2 - 1) - sqrt(Npar2)*yn)/(Npar2 - 1)/betath[0]; 1474 } else { 1475 if (Npar2 == 1) { 1476 pmin = fabs(yn2 - 1)/yn/betath[0]/2; 1477 } else { 1478 if (Npar2 < 1) { 1479 if (yn2 > 1 - Npar2) { 1480 pmin = fabs(sqrt(yn2 + Npar2 - 1) - sqrt(Npar2)*yn)/(1 - Npar2)/betath[0]; 1481 } else { 1482 pmin = pmax + 1; 1483 } 1484 }}} 1485 1486 if (pmin > pmax) { 1487 if (yn <= 1) { /* LFS */ 1488 if (nmin > 0) { 1489 nmin = nmin + 1; 1490 } 1491 } else { /* HFS */ 1492 nmax = nmax - 1; 1493 flagn = 1; 1494 } 1495 } 1496 } 1497 1498 /*mexPrintf("nmin,nmax:%i,%i\n",nmin,nmax);*/ 1499 1500 /* wave absorption coefficient */ 1501 1502 if (flag_f0 == 1) {/* non-Maxwellian electron distribution */ 1503 1504 Xf0 = mxCalloc(distriparam.npn[0]*distriparam.nmhu[0],sizeof(double)); 1505 dXf0drho = mxCalloc(distriparam.npn[0]*distriparam.nmhu[0],sizeof(double)); 1506 d2Xf0drho2 = mxCalloc(distriparam.npn[0]*distriparam.nmhu[0],sizeof(double)); 1507 PSI = mxCalloc(1,sizeof(double)); 1508 1509 if (flag_metric == 1) 1510 { 1511 ppvald_1D(raydistri.f0_fit,rayparam.dS[0],Y[0],Xf0,dXf0drho,d2Xf0drho2); 1512 ppvald_2D(raydistri.PSI_fit,rayparam.dS[0],Y[0],Y[1],PSI,&dummy1,&dummy1,&dummy1,&dummy1,&dummy1); 1513 } 1514 else 1515 { 1516 double rho,theta; 1517 substitution(rayequil,rayparam,equilparam,&rho,&theta,Y); 1518 ppvald_1D(raydistri.f0_fit,rayparam.dS[0],rho,Xf0,dXf0drho,d2Xf0drho2); 1519 ppvald_2D(raydistri.PSI_fit,rayparam.dS[0],rho,theta,PSI,&dummy1,&dummy1,&dummy1,&dummy1,&dummy1); 1520 } 1521 1522 pn = distriparam.pn; 1523 npn = distriparam.npn[0]; 1524 1525 mhu = distriparam.mhu; 1526 nmhu = distriparam.nmhu[0]; 1527 1528 /********** WARNING: alphaphi_jd MUST be modified before using these quantities YP **************/ 1529 1530 /*wpn2[0] = qe*qe*distriparam.ne_ref[0]/epsi0/me/Y[6]/Y[6];*/ /*electrons */ 1531 /*betath[0] = distriparam.betath_ref[0];*/ 1532 1533 /************************************************************************************************/ 1534 1535 } else {/* Maxwellian electron distribution */ 1536 1537 Xf0 = mxCalloc(1,sizeof(double)); 1538 dXf0drho = mxCalloc(1,sizeof(double)); 1539 d2Xf0drho2 = mxCalloc(1,sizeof(double)); 1540 1541 PSI = mxCalloc(1,sizeof(double)); 1542 1543 pn = mxCalloc(1,sizeof(double)); 1544 npn = 1; 1545 1546 mhu = mxCalloc(1,sizeof(double)); 1547 nmhu = 1; 1548 } 1549 1550 for (n=nmin;n int)rayparam.rel_opt[0],(int)rayparam.nperp[0],pmax,npn,pn,nmhu,mhu,Xf0,PSI); 1552 } 1553 1554 if (flag_f0 == 1) {/* non-Maxwellian electron distribution */ 1555 mxFree(Xf0); 1556 mxFree(dXf0drho); 1557 mxFree(d2Xf0drho2); 1558 mxFree(PSI); 1559 } else {/* Maxwellian electron distribution */ 1560 mxFree(Xf0); 1561 mxFree(dXf0drho); 1562 mxFree(d2Xf0drho2); 1563 mxFree(PSI); 1564 mxFree(pn); 1565 mxFree(mhu); 1566 } 1567 1568 rayproc[0] = cabs(Dtot); 1569 disprel(dDtotdY,&Dtot,X,dNperpdY,Nperp,dN2dY,N2,dNpardY,Npar,1); 1570 rayproc[1] = Npar; 1571 rayproc[2] = creal(Nperp); 1572 rayproc[3] = creal(epolp); 1573 rayproc[4] = cimag(epolp); 1574 rayproc[5] = creal(epolm); 1575 rayproc[6] = cimag(epolm); 1576 rayproc[7] = creal(epolz); 1577 rayproc[8] = cimag(epolz); 1578 rayproc[9] = phix; 1579 rayproc[10] = phiy; 1580 rayproc[11] = phiz; 1581 rayproc[12] = alphaphi; 1582 rayproc[13] = raymagnetic.xn[0]; 1583 rayproc[14] = raymagnetic.yn[0]; 1584 rayproc[15] = raymagnetic.B[0]; 1585 rayproc[16] = raymagnetic.Brhon[0]; 1586 rayproc[17] = raymagnetic.Bsn[0]; 1587 rayproc[18] = raymagnetic.Bzn[0]; 1588 rayproc[19] = raymagnetic.rn[0]; 1589 rayproc[20] = raymagnetic.salpha[0]; 1590 rayproc[21] = raymagnetic.gradrhon[0]; 1591 rayproc[22] = eikval; 1592 rayproc[23] = raymagnetic.Upsilonn[0]; 1593 1594 rayproc[24] = rayprofiles.Te[0]; 1595 rayproc[25] = rayprofiles.ne[0]; 1596 1597 for (i=0;i int reflection(flag,X,rayparam,equilparam,fluctparam,raymagnetic,rayprofiles,krho2,m2,kz2,Y0,Y,rayequil,rayfluctuations,flag_fluct)/*Doesn't have to be modified under a change of metric that only applies to the center of the grid*/ 1607 double flag; 1608 susceptibilitytensor_format X; 1609 rayparam_format rayparam; 1610 equilparam_format equilparam; 1611 fluctparam_format fluctparam; 1612 raymagnetic_format raymagnetic; 1613 rayprofiles_format rayprofiles; 1614 double *krho2,*m2,*kz2; 1615 double Y0[],Y[]; 1616 rayequil_format rayequil; 1617 rayfluctuations_format rayfluctuations; 1618 int flag_fluct; 1619 { 1620 double complex Dtot,dDtotdY[MC]; 1621 1622 double Npar,Npar2,dNpardY[MC]; 1623 double complex Nperp,dNperpdY[MC]; 1624 double complex N2,dN2dY[MC],eikval; 1625 1626 double wcn[equilparam.ns[0]+1],wpn2[equilparam.ns[0]+1],betath[equilparam.ns[0]+1]; 1627 1628 double alpha_rho,alpha_theta,alpha_z; 1629 double beta_r,beta_theta,beta_z; 1630 double a11,a12,a13,a21,a22,a23,a31,a32,a33,b1,b2,b3,det; 1631 double acc,krho_dsolve; 1632 1633 double Yguess[MC]; 1634 1635 1636 /* Equilibrium interpolation at ray location */ 1637 if (flag == 0) { 1638 interpequil(rayparam,raymagnetic,rayprofiles,equilparam,fluctparam,Y0,Y,rayequil,rayfluctuations,flag_fluct,1); 1639 } else { 1640 interpequil_test(raymagnetic,rayprofiles,equilparam,Y,flag); 1641 } 1642 1643 /* Refractive index calculation */ 1644 1645 rayindex(&Nperp,dNperpdY,&N2,dN2dY,1,Y,raymagnetic,equilparam,&Npar,dNpardY,&eikval); 1646 1647 /* Susceptibility tensor */ 1648 1649 susceptibility(X,Nperp,dNperpdY,wcn,wpn2,betath,rayparam.tensortype[0],(int)rayparam.ncyclharm[0],equilparam,raymagnetic,rayprofiles,Npar,dNpardY,Y[6]); 1650 1651 /* dispersion relation */ 1652 1653 disprel(dDtotdY,&Dtot,X,dNperpdY,Nperp,dN2dY,N2,dNpardY,Npar,3); 1654 /*mexPrintf("Disprel_in reflection:%g\n",creal(Dtot));*/ 1655 1656 /* calculation of the rotation angle beta around Bfield direction with the condition k2.grad(rho) = -k1.grad(rho) where rho is the perturbed magnetic flux surface */ 1657 1658 alpha_rho = raymagnetic.gradrhon[0]*raymagnetic.drhoripdY[0]; 1659 alpha_theta = raymagnetic.drhoripdY[1]/raymagnetic.rn[0]; 1660 alpha_z = raymagnetic.drhoripdY[2]/raymagnetic.Upsilonn[0]; 1661 1662 beta_r = -raymagnetic.salpha[0]*raymagnetic.Bzn[0]*alpha_rho + alpha_theta*raymagnetic.Bzn[0] + alpha_z*(raymagnetic.Brhon[0]*raymagnetic.salpha[0] - raymagnetic.Bsn[0]*raymagnetic.calpha[0]); 1663 beta_theta = -raymagnetic.calpha[0]*raymagnetic.Bzn[0]*alpha_rho + alpha_z*(raymagnetic.Brhon[0]*raymagnetic.calpha[0] + raymagnetic.Bsn[0]*raymagnetic.salpha[0]); 1664 beta_z = raymagnetic.Bsn[0]*alpha_rho - alpha_theta*(raymagnetic.Brhon[0]*raymagnetic.calpha[0] + raymagnetic.Bsn[0]*raymagnetic.salpha[0]); 1665 1666 a11 = raymagnetic.gradrhon[0]*alpha_rho; 1667 a12 = (alpha_theta*raymagnetic.calpha[0] - alpha_rho*raymagnetic.salpha[0])/raymagnetic.rn[0]; 1668 a13 = alpha_z/raymagnetic.Upsilonn[0]; 1669 1670 a21 = raymagnetic.gradrhon[0]*raymagnetic.Brhon[0]; 1671 a22 = (raymagnetic.Bsn[0]*raymagnetic.calpha[0] - raymagnetic.Brhon[0]*raymagnetic.salpha[0])/raymagnetic.rn[0]; 1672 a23 = raymagnetic.Bzn[0]/raymagnetic.Upsilonn[0]; 1673 1674 a31 = raymagnetic.gradrhon[0]*(beta_r*raymagnetic.calpha[0] - beta_theta*raymagnetic.salpha[0]); 1675 a32 = beta_theta/raymagnetic.rn[0]; 1676 a33 = beta_z/raymagnetic.Upsilonn[0]; 1677 1678 b1 = -a11*Y[3] - a12*Y[4] - a13*Y[5]; 1679 b2 = a21*Y[3] + a22*Y[4] + a23*Y[5]; 1680 b3 = a31*Y[3] + a32*Y[4] + a33*Y[5]; 1681 1682 det = a11*(a22*a33 - a23*a32) - a21*(a12*a33 - a32*a13) + a31*(a12*a23 - a22*a13); 1683 1684 krho2[0] = (b1*(a22*a33 - a23*a32) - b2*(a12*a33 - a32*a13) + b3*(a12*a23 - a22*a13))/det; 1685 m2[0] = (a11*(b2*a33 - a23*b3) - a21*(b1*a33 - b3*a13) + a31*(b1*a23 - b2*a13))/det; 1686 kz2[0] = (a11*(a22*b3 - b2*a32) - a21*(a12*b3 - a32*b1) + a31*(a12*b2 - a22*b1))/det; 1687 1688 /* simple expressions for the axisymmetric case only for benchmarking */ 1689 1690 /* mexPrintf("General calculation -> krho2[0],m2[0],n2[0]:%g,%g,%g\n",krho2[0],m2[0],n2[0]); 1691 1692 krho2[0] = 2.0*Y[4]*raymagnetic.salpha[0]/raymagnetic.rn[0]/raymagnetic.gradrhon[0] - Y[3]; 1693 m2[0] = Y[4]; 1694 n2[0] = Y[5]; 1695 1696 mexPrintf("Axisymmetric case -> krho2[0],m2[0],n2[0]:%g,%g,%g\n",krho2[0],m2[0],n2[0]); 1697 mexPrintf("Initial values -> krho1[0],m1[0],n1[0]:%g,%g,%g\n",Y[3],Y[4],Y[5]); 1698 1699 mexPrintf("General calculation -> alpha_rho,alpha_theta,alpha_z:%g,%g,%g\n",alpha_rho,alpha_theta,alpha_z); 1700 mexPrintf("General calculation -> raymagnetic.Brhon[0],raymagnetic.Bsn[0],raymagnetic.Bzn[0]:%g,%g,%g\n",raymagnetic.Brhon[0],raymagnetic.Bsn[0],raymagnetic.Bzn[0]); 1701 mexPrintf("General calculation -> raymagnetic.calpha[0],raymagnetic.salpha[0],raymagnetic.gradrhon[0]:%g,%g,%g\n",raymagnetic.calpha[0],raymagnetic.salpha[0],raymagnetic.gradrhon[0]); 1702 */ 1703 1704 /*correct lack of accuracy of the magnetic topology in presence of fluctuation when Brho is not exatly zero */ 1705 1706 acc = raymagnetic.Brhon[0]*(alpha_rho - alpha_theta*raymagnetic.salpha[0]) + raymagnetic.Bsn[0]*alpha_theta*raymagnetic.calpha[0] + alpha_z*raymagnetic.Bzn[0]; 1707 1708 if (acc != 0) { 1709 1710 Yguess[0] = Y[0]; 1711 Yguess[1] = Y[1]; 1712 Yguess[2] = Y[2]; 1713 Yguess[3] = krho2[0]; 1714 Yguess[4] = m2[0]; 1715 Yguess[5] = kz2[0]; 1716 Yguess[6] = Y[6]; 1717 dsolve(1,equilparam.ns[0],&krho_dsolve,Y0,Yguess,raymagnetic,rayprofiles,X,rayparam,equilparam,fluctparam,rayequil,rayfluctuations,flag,flag_fluct); 1718 /* mexPrintf("General calculation -> krho_in,krho_reflection,krho_reflection_dsolve:%g,%g,%g\n",Y[3],krho2[0],krho_dsolve);*/ 1719 krho2[0] = krho_dsolve; 1720 mexPrintf("The dispersion relation is solved at the reflection point to avoid cumulative propagation of numerical errors.\n"); 1721 if (fabs((krho_dsolve - krho2[0])/krho2[0]) > 1e-3) mexPrintf("WARNING: The relative difference between krho after reflection and krho after dsolve exceeds 1e-3.\n"); 1722 1723 } 1724 1725 return(0); 1726 } 1727 1728 1729 void dsolve(mode,ns,krho,Y0,Y,raymagnetic,rayprofiles,X,rayparam,equilparam,fluctparam,rayequil,rayfluctuations,flag,flag_fluct)/*Doesn't have to be modified under a change of metric that only applies to the grid's center*/ 1730 int mode,ns; 1731 double *krho; 1732 double Y0[],Y[]; 1733 raymagnetic_format raymagnetic; 1734 rayprofiles_format rayprofiles; 1735 susceptibilitytensor_format X; 1736 rayparam_format rayparam; 1737 equilparam_format equilparam; 1738 fluctparam_format fluctparam; 1739 rayequil_format rayequil; 1740 rayfluctuations_format rayfluctuations; 1741 double flag; 1742 int flag_fluct; 1743 { 1744 double Npar,dNpardY[MC]; 1745 double complex Nperp,dNperpdY[MC]; 1746 double complex N2,dN2dY[MC],eikval; 1747 1748 double frac,fracmax,exp,tol; 1749 double krho0,krho1,krho2,dkrho; 1750 double complex cD0,cD1,dDtotdY[MC]; 1751 double D0,D1,D2; 1752 int maxit; 1753 1754 double wcn[ns+1],wpn2[ns+1],betath[ns+1]; 1755 register int j; 1756 1757 frac = 1 - 1e-4; 1758 fracmax = 2; 1759 exp = -1.5; 1760 tol = 1e-12; 1761 1762 maxit = 50; 1763 1764 if (equilparam.zZi[0] > 0) { 1765 1766 /* Equilibrium interpolation at ray location */ 1767 if (flag == 0) { 1768 interpequil(rayparam,raymagnetic,rayprofiles,equilparam,fluctparam,Y0,Y,rayequil,rayfluctuations,flag_fluct,1); 1769 } else { 1770 interpequil_test(raymagnetic,rayprofiles,equilparam,Y,flag); 1771 } 1772 1773 krho0 = Y[3]; 1774 krho1 = frac*krho0; 1775 1776 rayindex(&Nperp,dNperpdY,&N2,dN2dY,1,Y,raymagnetic,equilparam,&Npar,dNpardY,&eikval); 1777 if (mode > 0) {/* plasma case */ 1778 susceptibility(X,Nperp,dNperpdY,wcn,wpn2,betath,rayparam.tensortype[0],(int)rayparam.ncyclharm[0],equilparam,raymagnetic,rayprofiles,Npar,dNpardY,Y[6]); 1779 } 1780 disprel(dDtotdY,&cD0,X,dNperpdY,Nperp,dN2dY,N2,dNpardY,Npar,2); 1781 D0 = creal(cD0);/* to be changed if non-hermitian susceptibility tensors are used */ 1782 /* mexPrintf("krho0,D0:%g,%g\n",krho0,D0); */ 1783 1784 Y[3] = krho1; 1785 rayindex(&Nperp,dNperpdY,&N2,dN2dY,1,Y,raymagnetic,equilparam,&Npar,dNpardY,&eikval); 1786 if (mode > 0) {/* plasma case */ 1787 susceptibility(X,Nperp,dNperpdY,wcn,wpn2,betath,rayparam.tensortype[0],(int)rayparam.ncyclharm[0],equilparam,raymagnetic,rayprofiles,Npar,dNpardY,Y[6]); 1788 } 1789 disprel(dDtotdY,&cD1,X,dNperpdY,Nperp,dN2dY,N2,dN2dY,Npar,2); 1790 D1 = creal(cD1);/* to be changed if non-hermitian susceptibility tensors are used */ 1791 /* mexPrintf("krho1,D1:%g,%g\n",krho1,D1); */ 1792 1793 /* Search for root bounding interval */ 1794 1795 while ((D1*D0 > 0) && (fracmax < 100)) { 1796 1797 frac = pow(frac,exp); 1798 krho1 = frac*krho0; 1799 1800 Y[3] = krho1; 1801 rayindex(&Nperp,dNperpdY,&N2,dN2dY,1,Y,raymagnetic,equilparam,&Npar,dNpardY,&eikval); 1802 if (mode > 0) {/* plasma case */ 1803 susceptibility(X,Nperp,dNperpdY,wcn,wpn2,betath,rayparam.tensortype[0],(int)rayparam.ncyclharm[0],equilparam,raymagnetic,rayprofiles,Npar,dNpardY,Y[6]); 1804 } 1805 disprel(dDtotdY,&cD1,X,dNperpdY,Nperp,dN2dY,N2,dNpardY,Npar,2); 1806 D1 = creal(cD1);/* to be changed if non-hermitian susceptibility tensors are used */ 1807 /*mexPrintf("krho1,D1:%g,%g\n",krho1,D1);*/ 1808 } 1809 1810 if (D1*D0 > 0) { 1811 krho[0] = krho0; /* put error message */ 1812 } 1813 /* else if (fabs(D0) < tol){ 1814 krho[0] = krho0; 1815 } 1816 else if (fabs(D1) < tol){ 1817 krho[0] = krho1; 1818 } 1819 */ 1820 else { 1821 if (fabs(D0) < fabs(D1)) { /*Closest root is set to latest value. */ 1822 krho2 = krho0; 1823 krho0 = krho1; 1824 krho1 = krho2; 1825 D2 = D0; 1826 D0 = D1; 1827 D1 = D2; 1828 } 1829 1830 j = 0; 1831 1832 /* mexPrintf("fabs(D1),tol,j,maxit:%g,%g,%d,%d\n",fabs(D1),tol,j,maxit); */ 1833 1834 while ((fabs(D1) > tol) && (j < maxit)) { /*Secant loop. */ 1835 1836 /* mexPrintf("krho0,D0,krho1,D1,frac,tol:%g,%g,%g,%g,%g,%g\n",krho0,D0,krho1,D1,frac,tol); */ 1837 1838 dkrho = (krho0 - krho1)*D1/(D1-D0); /*Increment with respect to latest value. */ 1839 krho0 = krho1; 1840 D0 = D1; 1841 krho1 += dkrho; 1842 1843 Y[3] = krho1; 1844 rayindex(&Nperp,dNperpdY,&N2,dN2dY,1,Y,raymagnetic,equilparam,&Npar,dNpardY,&eikval); 1845 if (mode > 0) {/* plasma case */ 1846 susceptibility(X,Nperp,dNperpdY,wcn,wpn2,betath,rayparam.tensortype[0],(int)rayparam.ncyclharm[0],equilparam,raymagnetic,rayprofiles,Npar,dNpardY,Y[6]); 1847 } 1848 disprel(dDtotdY,&cD1,X,dNperpdY,Nperp,dN2dY,N2,dNpardY,Npar,2); 1849 D1 = creal(cD1);/* to be changed if non-hermitian susceptibility tensor are used */ 1850 /* mexPrintf("krho1,D1:%g,%g\n",krho1,D1); */ 1851 } 1852 1853 if (fabs(D1) <= tol) { /*Convergence. */ 1854 krho[0] = krho1; 1855 } 1856 else { 1857 krho[0] = krho2; /* put error message */ 1858 } 1859 } 1860 1861 1862 /* krho[0] = -Y[3];*/ /* old method not accurate */ 1863 } else { 1864 krho[0] = Y[3]; 1865 } 1866 1867 } 1868 1869 1870 void disprel(dDtotdY,Dtot,X,dNperpdY,Nperp,dN2dY,N2,dNpardY,Npar,flag)/*Doesn't have to be modified under a change of metric*/ 1871 double complex dDtotdY[],*Dtot; 1872 susceptibilitytensor_format X; 1873 double complex dNperpdY[],Nperp,dN2dY[],N2; 1874 double dNpardY[],Npar; 1875 int flag; 1876 { 1877 double complex D[43],dDdY[43][MC],N6,dN6m1; 1878 1879 double complex Nperp4,Nperp3,Nperp2,Nperp1; 1880 double Npar4,Npar3,Npar2,Npar1; 1881 double complex Xxx,Xxy,Xxz,Xyy,Xyz,Xzz; 1882 double complex Xxx2,Xxy2,Xxz2,Xyy2,Xyz2,Xzz2; 1883 1884 int i,j; 1885 1886 Nperp1 = Nperp; 1887 Nperp2 = Nperp1*Nperp1; 1888 Nperp3 = Nperp1*Nperp1*Nperp1; 1889 Nperp4 = Nperp1*Nperp1*Nperp1*Nperp1; 1890 Npar1 = Npar; 1891 Npar2 = Npar1*Npar1; 1892 Npar3 = Npar1*Npar1*Npar1; 1893 Npar4 = Npar1*Npar1*Npar1*Npar1; 1894 1895 N6 = N2*N2*N2; 1896 1897 1898 /* mexPrintf("N2,dN2dY[i],%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g,%5.100g\n",N2,dN2dY[0],dN2dY[1],dN2dY[2],dN2dY[3],dN2dY[4],dN2dY[5],dN2dY[6],dN2dY[7]); */ 1899 1900 1901 Xxx = X.Xxx[0]; 1902 Xxy = X.Xxy[0]; 1903 Xxz = X.Xxz[0]; 1904 Xyy = X.Xyy[0]; 1905 Xyz = X.Xyz[0]; 1906 Xzz = X.Xzz[0]; 1907 Xxx2 = X.Xxx[0]*X.Xxx[0]; 1908 Xxy2 = X.Xxy[0]*X.Xxy[0]; 1909 Xxz2 = X.Xxz[0]*X.Xxz[0]; 1910 Xyy2 = X.Xyy[0]*X.Xyy[0]; 1911 Xyz2 = X.Xyz[0]*X.Xyz[0]; 1912 Xzz2 = X.Xzz[0]*X.Xzz[0]; 1913 1914 /* 1915 mexPrintf("Nperp4r,Nperp4i:%g,%g\n",creal(Nperp4),cimag(Nperp4)); 1916 mexPrintf("Npar:%g\n",Npar1); 1917 mexPrintf("Nperpr,Nperpi:%g,%g\n",creal(Nperp1),cimag(Nperp1)); 1918 mexPrintf("Xxxr,XXxxi:%g,%g\n",creal(Xxx),cimag(Xxx)); 1919 mexPrintf("Xxyr,XXxyi:%g,%g\n",creal(Xxy),cimag(Xxy)); 1920 mexPrintf("Xxzr,XXxzi:%g,%g\n",creal(Xxz),cimag(Xxz)); 1921 mexPrintf("Xyyr,XXyyi:%g,%g\n",creal(Xyy),cimag(Xyy)); 1922 mexPrintf("Xyzr,XXyzi:%g,%g\n",creal(Xyz),cimag(Xyz)); 1923 mexPrintf("Xzzr,XXzzi:%g,%g\n",creal(Xzz),cimag(Xzz)); 1924 1925 double complex Dtot1; 1926 Dtot1 = (Xxx+1)*Nperp4/N6+2*Npar1*Xxz*Nperp3/N6-(-2*Npar2+Xyy-Npar2*Xzz+Xxy2+Xzz-Xxz2+Xxx*Xzz+Xxx*Xyy+2+2*Xxx-Xxx*Npar2)*Nperp2/N6-(2*Npar1*Xxz+2*Npar1*Xyy*Xxz-2*Xxy*Xyz*Npar-2*Npar3*Xxz)*Nperp1/N6-(-1-Xxx*Xyz2-Xxy2*Xzz+Xyy*Xxz2-2*Xxy*Xyz*Xxz-Xxx*Xyy*Xzz-Xzz+2*Npar2-Xyy-Xyz2-Npar4-Xxx-Xxy2+Xxz2+2*Npar2*Xzz-Xyy*Xzz+Npar2*Xyy-Xxx*Xzz+Xxx*Npar2-Xxx*Xyy-Npar4*Xzz+Npar2*Xyz2-Npar2*Xxz2+Npar2*Xyy*Xzz+Xxx*Npar2*Xzz)/N6; 1927 mexPrintf("Dtot1:%g\n",Dtot1); 1928 */ 1929 if ((flag == 1) || (flag == 3)) { 1930 1931 for (i = 0;i for (i = 0;i for (i = 0;i<43;i++) { 1985 for (j=0;j if ((flag == 2) || (flag == 3)) { 1992 1993 D[0] = Nperp4/N6; 1994 D[1] = Xxx*Nperp4/N6; 1995 D[2] = 2.0*Npar1*Xxz*Nperp3/N6; 1996 D[3] = Npar2*Xxx*Nperp2/N6; 1997 D[4] = Npar2*Xzz*Nperp2/N6; 1998 D[5] = 2.0*Npar2*Nperp2/N6; 1999 D[6] = -2.0*Xxx*Nperp2/N6; 2000 D[7] = -Xyy*Nperp2/N6; 2001 D[8] = -Xzz*Nperp2/N6; 2002 D[9] = -Xxx*Xzz*Nperp2/N6; 2003 D[10] = Xxz2*Nperp2/N6; 2004 D[11] = -Xxx*Xyy*Nperp2/N6; 2005 D[12] = -Xxy2*Nperp2/N6; 2006 D[13] = -2.0*Nperp2/N6; 2007 D[14] = -2.0*Npar1*Xyy*Xxz*Nperp1/N6; 2008 D[15] = 2.0*Npar1*Xxy*Xyz*Nperp1/N6; 2009 D[16] = -2.0*Npar1*Xxz*Nperp1/N6; 2010 D[17] = 2.0*Npar3*Xxz*Nperp1/N6; 2011 D[18] = 1/N6; 2012 D[19] = Npar4*Xzz/N6; 2013 D[20] = Npar4/N6; 2014 D[21] = Npar2*Xxz2/N6; 2015 D[22] = -Npar2*Xyy*Xzz/N6; 2016 D[23] = -Npar2*Xxx*Xzz/N6; 2017 D[24] = -2.0*Npar2*Xzz/N6; 2018 D[25] = -Npar2*Xyy/N6; 2019 D[26] = -Npar2*Xyz2/N6; 2020 D[27] = -Npar2*Xxx/N6; 2021 D[28] = -2.0*Npar2/N6; 2022 D[29] = Xyy*Xzz/N6; 2023 D[30] = Xxx*Xzz/N6; 2024 D[31] = Xxx*Xyy/N6; 2025 D[32] = Xxx*Xyz2/N6; 2026 D[33] = Xyz2/N6; 2027 D[34] = Xxx/N6; 2028 D[35] = Xxy2/N6; 2029 D[36] = Xxy2*Xzz/N6; 2030 D[37] = -Xxz2/N6; 2031 D[38] = -Xyy*Xxz2/N6; 2032 D[39] = Xyy/N6; 2033 D[40] = Xzz/N6; 2034 D[41] = Xxx*Xyy*Xzz/N6; 2035 D[42] = 2.0*Xxy*Xyz*Xxz/N6; 2036 2037 /* for (i = 0;i<43;i++) { 2038 mexPrintf("i,Dr,Di:%d,%g\n",i,creal(D[i]),cimag(D[i])); 2039 }*/ 2040 2041 Dtot[0] = 0.0; 2042 for (i = 0;i<43;i++) { 2043 Dtot[0] = Dtot[0] + D[i]; 2044 } 2045 2046 /* mexPrintf("Dtot:%g\n",Dtot[0]);*/ 2047 } 2048 2049 } 2050 2051 void susceptibility(X,Nperp,dNperpdY,wcn,wpn2,betath,tensortype,ncyclharm,equilparam,raymagnetic,rayprofiles,Npar,dNpardY,omega)/*Doesn't have to be modified under a change of metric*/ 2052 susceptibilitytensor_format X; 2053 double complex Nperp,dNperpdY[]; 2054 double wcn[],wpn2[],betath[]; 2055 double tensortype,omega; 2056 int ncyclharm; 2057 double Npar,dNpardY[]; 2058 2059 raymagnetic_format raymagnetic; 2060 rayprofiles_format rayprofiles; 2061 equilparam_format equilparam; 2062 { 2063 double qe = 1.602176462e-19;/*Absolute value of the electron charge (C) */ 2064 double me = 9.10938188e-31;/*Electron rest mass (Kg) */ 2065 double mp = 1.67262158e-27;/*Proton rest mass (Kg) */ 2066 double epsi0 = 8.854187818e-12;/*Free space permittivity (F/m) */ 2067 double mu0 = 12.566370614e-7;/*Free space permeability (F/m) */ 2068 double mc2 = 510.998902;/*Electron energy rest mass (keV) */ 2069 2070 double dwcndY[equilparam.ns[0]+1][MC],dwpn2dY[equilparam.ns[0]+1][MC],dbetathdY[equilparam.ns[0]+1][MC]; 2071 2072 int i,j,is; 2073 2074 2075 if (equilparam.zZi[0] > 0) { 2076 2077 for (i = 0;i < equilparam.ns[0] + 1; i++) {/*initialisation */ 2078 wcn[i] = 0.0; 2079 wpn2[i] = 0.0; 2080 betath[i] = 0.0; 2081 for (j=0;j /* Normalized parameters */ 2089 2090 wcn[0] = -qe*raymagnetic.B[0]/me/omega;/*electrons */ 2091 dwcndY[0][0] = -qe*raymagnetic.dBdY[0]/me/omega; 2092 dwcndY[0][1] = -qe*raymagnetic.dBdY[1]/me/omega; 2093 dwcndY[0][2] = -qe*raymagnetic.dBdY[2]/me/omega; 2094 dwcndY[0][6] = -wcn[0]; 2095 2096 wpn2[0] = qe*qe*rayprofiles.ne[0]/epsi0/me/omega/omega;/*electrons */ 2097 dwpn2dY[0][0] = qe*qe*rayprofiles.dnedY[0]/epsi0/me/omega/omega; 2098 dwpn2dY[0][1] = qe*qe*rayprofiles.dnedY[1]/epsi0/me/omega/omega; 2099 dwpn2dY[0][2] = qe*qe*rayprofiles.dnedY[2]/epsi0/me/omega/omega; 2100 dwpn2dY[0][6] = -2.0*wpn2[0]; 2101 2102 betath[0] = sqrt(rayprofiles.Te[0]/mc2); 2103 dbetathdY[0][0] = rayprofiles.dTedY[0]/betath[0]/2.0; 2104 dbetathdY[0][1] = rayprofiles.dTedY[1]/betath[0]/2.0; 2105 dbetathdY[0][2] = rayprofiles.dTedY[2]/betath[0]/2.0; 2106 2107 for (is = 1;is < equilparam.ns[0]+1; is++) { 2108 if (rayprofiles.zni[is-1] > 0.0) {/* only when ion density is positive */ 2109 wcn[is] = qe*equilparam.zZi[is-1]*raymagnetic.B[0]/equilparam.zmi[is-1]/mp/omega;/*ions */ 2110 dwcndY[is][0] = qe*equilparam.zZi[is-1]*raymagnetic.dBdY[0]/equilparam.zmi[is-1]/mp/omega; 2111 dwcndY[is][1] = qe*equilparam.zZi[is-1]*raymagnetic.dBdY[1]/equilparam.zmi[is-1]/mp/omega; 2112 dwcndY[is][2] = qe*equilparam.zZi[is-1]*raymagnetic.dBdY[2]/equilparam.zmi[is-1]/mp/omega; 2113 dwcndY[is][6] = -wcn[is]; 2114 2115 wpn2[is] = qe*equilparam.zZi[is-1]*qe*equilparam.zZi[is-1]*rayprofiles.zni[is-1]/epsi0/equilparam.zmi[is-1]/mp/omega/omega;/*ions */ 2116 dwpn2dY[is][0] = qe*equilparam.zZi[is-1]*qe*equilparam.zZi[is-1]*rayprofiles.dznidY[is-1][0]/epsi0/equilparam.zmi[is-1]/mp/omega/omega; 2117 dwpn2dY[is][1] = qe*equilparam.zZi[is-1]*qe*equilparam.zZi[is-1]*rayprofiles.dznidY[is-1][1]/epsi0/equilparam.zmi[is-1]/mp/omega/omega; 2118 dwpn2dY[is][2] = qe*equilparam.zZi[is-1]*qe*equilparam.zZi[is-1]*rayprofiles.dznidY[is-1][2]/epsi0/equilparam.zmi[is-1]/mp/omega/omega; 2119 dwpn2dY[is][6] = -2.0*wpn2[is]; 2120 2121 betath[is] = sqrt(rayprofiles.zTi[is-1]*me/equilparam.zmi[is-1]/mp/mc2); 2122 dbetathdY[is][0] = rayprofiles.dzTidY[is-1][0]/betath[is]/2.0; 2123 dbetathdY[is][1] = rayprofiles.dzTidY[is-1][1]/betath[is]/2.0; 2124 dbetathdY[is][2] = rayprofiles.dzTidY[is-1][2]/betath[is]/2.0; 2125 } 2126 } 2127 2128 if (tensortype == 0) { 2129 /* mexPrintf("Cold dielectric tensor\n"); */ 2130 coldtensor(X,Nperp,dNperpdY,equilparam.ns[0],ncyclharm,raymagnetic,Npar,dNpardY,wcn,dwcndY,wpn2,dwpn2dY,betath,dbetathdY); 2131 } 2132 if (tensortype == 1) { 2133 /* mexPrintf("Warm dielectric tensor\n"); 2134 warmtensor(X,Nperp,dNperpdY,equilparam.ns[0],ncyclharm,raymagnetic,Npar,dNpardY,wcn,dwcndY,wpn2,dwpn2dY,betath,dbetathdY); */ 2135 } 2136 if (tensortype == 2) { 2137 /* mexPrintf("Hot dielectric tensor\n");*/ 2138 hottensor(X,Nperp,dNperpdY,equilparam.ns[0],ncyclharm,raymagnetic,Npar,dNpardY,wcn,dwcndY,wpn2,dwpn2dY,betath,dbetathdY); 2139 } 2140 if (tensortype == 3) { 2141 /* mexPrintf("Weak relativistic dielectric tensor\n");*/ 2142 weakrelativistictensor(X,Nperp,dNperpdY,equilparam.ns[0],ncyclharm,raymagnetic,Npar,dNpardY,wcn,dwcndY,wpn2,dwpn2dY,betath,dbetathdY); 2143 } 2144 if (tensortype == 4) { 2145 /* mexPrintf("Full relativistic dielectric tensor\n"); 2146 fullrelativistictensor(X,Nperp,dNperpdY,equilparam.ns[0],ncyclharm,raymagnetic,Npar,dNpardY,wcn,dwcndY,wpn2,dwpn2dY,betath,dbetathdY); */ 2147 } 2148 2149 } else { 2150 vacuumtensor(X); 2151 } 2152 } 2153 2154 2155 void rayindex(Nperp,dNperpdY,N2,dN2dY,flag_metric,Y,raymagnetic,equilparam,Npar,dNpardY,eikval)/*Has to be modified under a change of metric*/ 2156 double complex *Nperp,*dNperpdY; 2157 double complex *N2,*dN2dY; 2158 int flag_metric; 2159 double Y[]; 2160 double *Npar,*dNpardY; 2161 raymagnetic_format raymagnetic; 2162 equilparam_format equilparam; 2163 double complex *eikval; 2164 { 2165 double dYdY[MC][MC]; 2166 2167 double Npar0,dNpar0dY,dNpar0dY1,dNpar0dY2,dNpar0dY3,dNpar0dY4,dNpar0dY5,dNpar0dY6; 2168 double Npar1,dNpar1dY,dNpar1dY1,dNpar1dY2,dNpar1dY3,dNpar1dY4,dNpar1dY5,dNpar1dY6; 2169 double Npar2,dNpar2dY,dNpar2dY1,dNpar2dY2,dNpar2dY3,dNpar2dY4,dNpar2dY5; 2170 double calpha_theta,salpha_theta,dcalpha_thetadx,dcalpha_thetady,dsalpha_thetadx,dsalpha_thetady; 2171 2172 double complex N21,dN21dY,dN21dY1,dN21dY2,dN21dY3; 2173 double complex N22,dN22dY,dN22dY1,dN22dY2,dN22dY3,dN22dY4,dN22dY5,dN22dY6; 2174 double complex N23,dN23dY,dN23dY1,dN23dY2,dN23dY3; 2175 double complex N24,dN24dY,dN24dY1,dN24dY2,dN24dY3; 2176 2177 2178 double complex divN11,divN12,divN13,divN14,divN15; 2179 double complex divN21,divN22,divN23,divN24,divN25; 2180 double complex divN31,divN32; 2181 double complex divN1,divN2,divN3; 2182 2183 double ap,cnorm; 2184 double theta; 2185 2186 register int i,j; 2187 2188 /*Covariant matrix */ 2189 2190 for (i=0;i for (j=0;j if ((i==j) && (i<7)) { 2193 dYdY[i][j] = 1.0; 2194 } else { 2195 dYdY[i][j] = 0.0; 2196 } 2197 } 2198 } 2199 2200 2201 for (i=0;i /*initialisation */ 2202 dNpardY[i] = 0.0; 2203 dNperpdY[i] = 0.0; 2204 dN2dY[i] = 0.0; 2205 } 2206 2207 ap = equilparam.ap[0]; 2208 cnorm = CLUM/ap/Y[6]; 2209 2210 /* mexPrintf("clum_norm,ap,CLUM,Y[6]:%g,%g,%g,%g\n",cnorm,ap,CLUM,Y[6]); */ 2211 2212 /* Definition of the rayindex and its derivatives in flux coordinates */ 2213 2214 if (flag_metric == 1) 2215 { 2216 2217 Npar0 = Y[3]*raymagnetic.gradrhon[0]*raymagnetic.Brhon[0]; 2218 Npar1 = Y[4]*(raymagnetic.calpha[0]*raymagnetic.Bsn[0] - raymagnetic.salpha[0]*raymagnetic.Brhon[0])/raymagnetic.rn[0]; 2219 Npar2 = Y[5]*raymagnetic.Bzn[0]/raymagnetic.Upsilonn[0]; 2220 Npar[0] = cnorm*(Npar0 + Npar1 + Npar2); 2221 /* mexPrintf("Npar0,Npar1,Npar2:%g,%g,%g\n",Npar0,Npar1,Npar2); */ 2222 /* mexPrintf("Nparth:%g\n",Npar[0]); */ 2223 /* mexPrintf("Y[0],Y[1],Y[2],Y[3],Y[4],Y[5]:%g,%g,%g,%g,%g,%g\n",Y[0],Y[1],Y[2],Y[3],Y[4],Y[5]); */ 2224 /* mexPrintf("Y[4],raymagnetic.calpha[0],raymagnetic.Brhon[0],raymagnetic.Bsn[0],raymagnetic.rn[0],Y[5],raymagnetic.Bzn[0],raymagnetic.xn[0]:%g,%g,%g,%g,%g,%g,%g\n",Y[4],raymagnetic.calpha[0],raymagnetic.Brhon[0],raymagnetic.Bsn[0],raymagnetic.rn[0],Y[5],raymagnetic.Bzn[0],raymagnetic.xn[0]); */ 2225 2226 2227 for (i=0;i /*mexPrintf("i,dNpardY[i]:%d,%g\n",i,dNpardY[i]);*/ 2256 /*mexPrintf("i,dYdY[3][i],dYdY[4][i],dYdY[5][i]:%d,%g,%g,%g\n",i,dYdY[3][i],dYdY[4][i],dYdY[4][i]);*/ 2257 } 2258 N21 = raymagnetic.gradrhon[0]*raymagnetic.gradrhon[0]*Y[3]*Y[3]; 2259 N22 = -2.0*raymagnetic.gradrhon[0]*raymagnetic.salpha[0]*Y[4]*Y[3]/raymagnetic.rn[0]; 2260 N23 = Y[4]*Y[4]/raymagnetic.rn[0]/raymagnetic.rn[0]; 2261 N24 = Y[5]*Y[5]/raymagnetic.Upsilonn[0]/raymagnetic.Upsilonn[0]; 2262 2263 N2[0] = cnorm*cnorm*(N21 + N22 + N23 + N24); 2264 Nperp[0] = sqrt(N2[0] - Npar[0]*Npar[0]); 2265 2266 /*mexPrintf("Npar,Nperp,N2:%g,%g,%g,%g,%g\n",Npar[0],Nperp[0],N2[0]);*/ 2267 2268 for (i=0;i /* mexPrintf("Y[]:%g,%g,%g,%g,%g,%g,%g\n",Y[0],Y[1],Y[2],Y[3],Y[4],Y[5]); 2305 mexPrintf("r,2*r*drdY[]:%g,%g,%g,%g,%g,%g,%g,%g,%g\n",raymagnetic.rn[0],2.0*raymagnetic.rn[0]*raymagnetic.drndY[0],2.0*raymagnetic.rn[0]*raymagnetic.drndY[1],2.0*raymagnetic.rn[0]*raymagnetic.drndY[2],2.0*raymagnetic.rn[0]*raymagnetic.drndY[3],2.0*raymagnetic.rn[0]*raymagnetic.drndY[4],2.0*raymagnetic.rn[0]*raymagnetic.drndY[5],2.0*raymagnetic.rn[0]*raymagnetic.drndY[6],2.0*raymagnetic.rn[0]*raymagnetic.drndY[7],2.0*raymagnetic.rn[0]*raymagnetic.drndY[8]); 2306 mexPrintf("dN2dY[]:%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g\n",dN2dY[0],dN2dY[1],dN2dY[2],dN2dY[3],dN2dY[4],dN2dY[5],dN2dY[6],dN2dY[7]); 2307 */ 2308 2309 divN11 = raymagnetic.dUpsilonndY[0]*raymagnetic.rn[0]*raymagnetic.gradrhon[0]*Y[3]/raymagnetic.calpha[0]; 2310 divN12 = raymagnetic.Upsilonn[0]*raymagnetic.drndY[0]*raymagnetic.gradrhon[0]*Y[3]/raymagnetic.calpha[0]; 2311 divN13 = raymagnetic.Upsilonn[0]*raymagnetic.rn[0]*raymagnetic.dgradrhondY[0]*Y[3]/raymagnetic.calpha[0]; 2312 divN14 = raymagnetic.Upsilonn[0]*raymagnetic.rn[0]*raymagnetic.gradrhon[0]*dYdY[3][0]/raymagnetic.calpha[0]; 2313 divN15 = -raymagnetic.Upsilonn[0]*raymagnetic.rn[0]*raymagnetic.gradrhon[0]*Y[3]*raymagnetic.dcalphadY[0]/raymagnetic.calpha[0]/raymagnetic.calpha[0]; 2314 2315 divN21 = dYdY[4][1]/raymagnetic.rn[0]/raymagnetic.calpha[0]/raymagnetic.Bsn[0]/raymagnetic.B[0]; 2316 divN22 = -Y[4]*raymagnetic.drndY[1]/raymagnetic.rn[0]/raymagnetic.rn[0]/raymagnetic.calpha[0]/raymagnetic.Bsn[0]/raymagnetic.B[0]; 2317 divN23 = -Y[4]*raymagnetic.dcalphadY[1]/raymagnetic.rn[0]/raymagnetic.calpha[0]/raymagnetic.calpha[0]/raymagnetic.Bsn[0]/raymagnetic.B[0]; 2318 divN24 = -Y[4]*raymagnetic.dBsndY[1]/raymagnetic.rn[0]/raymagnetic.calpha[0]/raymagnetic.Bsn[0]/raymagnetic.Bsn[0]/raymagnetic.B[0]; 2319 divN25 = -Y[4]*raymagnetic.dBdY[1]/raymagnetic.rn[0]/raymagnetic.calpha[0]/raymagnetic.Bsn[0]/raymagnetic.B[0]/raymagnetic.B[0]; 2320 2321 divN31 = dYdY[5][2]/raymagnetic.Upsilonn[0]; 2322 divN32 = -Y[5]*raymagnetic.dUpsilonndY[2]/raymagnetic.Upsilonn[0]/raymagnetic.Upsilonn[0]; 2323 2324 divN1 = (divN11 + divN12 + divN13 + divN14 + divN15)*raymagnetic.gradrhon[0]*raymagnetic.calpha[0]/raymagnetic.Upsilonn[0]/raymagnetic.rn[0]; 2325 divN2 = (divN21 + divN22 + divN23 + divN24 + divN25)*raymagnetic.Bsn[0]*raymagnetic.B[0]*raymagnetic.calpha[0]/raymagnetic.rn[0]; 2326 divN3 = (divN31 + divN32)/raymagnetic.Upsilonn[0]; 2327 2328 eikval[0] = cnorm*cabs(divN1 + divN2 + divN3)/N2[0]; 2329 2330 } 2331 else/*Cartesian ray index declaration, 06/06/16 update*/ 2332 /* In this section the array Y stands for Y=[x,y,phi,kx,kz,n,omega/c]*/ 2333 { 2334 2335 /* Declaration of cos(alpha-theta), sin(alpha-theta) */ 2336 2337 theta = atan2(Y[1],Y[0]); 2338 2339 calpha_theta = raymagnetic.calpha[0]*cos(theta) + raymagnetic.salpha[0]*sin(theta); 2340 2341 salpha_theta = raymagnetic.salpha[0]*cos(theta) - raymagnetic.calpha[0]*sin(theta); 2342 2343 2344 /* Declaration of the cartesian derivatives of cos(alpha-theta), sin(alpha-theta) */ 2345 2346 2347 dcalpha_thetadx = cos(theta)*(raymagnetic.dcalphadY[0] - raymagnetic.salpha[0]*sin(theta)/raymagnetic.rn[0]) + sin(theta)*(raymagnetic.dsalphadY[0] + raymagnetic.calpha[0]*sin(theta)/raymagnetic.rn[0]); 2348 2349 dcalpha_thetady = cos(theta)*(raymagnetic.dcalphadY[1] + raymagnetic.salpha[0]*cos(theta)/raymagnetic.rn[0]) + sin(theta)*(raymagnetic.dsalphadY[1] - raymagnetic.calpha[0]*cos(theta)/raymagnetic.rn[0]); 2350 2351 dsalpha_thetadx = cos(theta)*(raymagnetic.dsalphadY[0] + raymagnetic.calpha[0]*sin(theta)/raymagnetic.rn[0]) - sin(theta)*(raymagnetic.dcalphadY[0] - raymagnetic.salpha[0]*sin(theta)/raymagnetic.rn[0]); 2352 2353 dsalpha_thetady = cos(theta)*(raymagnetic.dsalphadY[1] - raymagnetic.calpha[0]*cos(theta)/raymagnetic.rn[0]) - sin(theta)*(raymagnetic.dcalphadY[1] + raymagnetic.salpha[0]*cos(theta)/raymagnetic.rn[0]); 2354 2355 double dsalpha_thetadY[MC]; 2356 double dcalpha_thetadY[MC]; 2357 2358 for(i=0;i if(i==0) 2361 { 2362 dsalpha_thetadY[i] = dsalpha_thetadx; 2363 dcalpha_thetadY[i] = dcalpha_thetadx; 2364 } 2365 else 2366 { 2367 if(i==1) 2368 { 2369 dsalpha_thetadY[i] = dsalpha_thetady; 2370 dcalpha_thetadY[i] = dcalpha_thetady; 2371 } 2372 else 2373 { 2374 dsalpha_thetadY[i] = 0; 2375 dcalpha_thetadY[i] = 0; 2376 } 2377 } 2378 } 2379 2380 /* Declaration of the parallel ray index */ 2381 2382 2383 Npar0 = Y[3]*(raymagnetic.Bsn[0]*salpha_theta + calpha_theta*raymagnetic.Brhon[0]); 2384 Npar1 = Y[4]*(raymagnetic.Bsn[0]*calpha_theta - salpha_theta*raymagnetic.Brhon[0]); 2385 Npar2 = Y[5]*raymagnetic.Bzn[0]/raymagnetic.Upsilonn[0]; 2386 2387 Npar[0] = cnorm*(Npar0 + Npar1 + Npar2); 2388 2389 /*Declaration of the parallel ray index first order derivatives*/ 2390 2391 for(i=0;i /* Declaration of the square rayindex and its derivatives */ 2422 2423 N2[0] = cnorm*cnorm*(pow(Y[3],2) + pow(Y[4],2) + pow(Y[5]/raymagnetic.Upsilonn[0],2)); 2424 2425 for(i=0;i /* Declaration of the perpendicular ray index and its first order derivatives */ 2447 2448 Nperp[0] = sqrt(N2[0]-pow(Npar[0],2));/*Perpendicular ray index*/ 2449 2450 for(i=0;i /* WKB approximation */ 2456 2457 eikval[0]=0.0;/*We will turn on this paramater later*/ 2458 } 2459 } 2460 2461 2462 void buildXstruc(X,dNperpdY,Xxx,Xxy,Xxz,Xyy,Xyz,Xzz,dXxxdNperp,dXxydNperp,dXxzdNperp,dXyydNperp,dXyzdNperp,dXzzdNperp,dXxxdNpar,dXxydNpar,dXxzdNpar,dXyydNpar,dXyzdNpar,dXzzdNpar,dXxxdbetath,dXxydbetath,dXxzdbetath,dXyydbetath,dXyzdbetath,dXzzdbetath,dXxxdwcn,dXxydwcn,dXxzdwcn,dXyydwcn,dXyzdwcn,dXzzdwcn,dXxxdwpn2,dXxydwpn2,dXxzdwpn2,dXyydwpn2,dXyzdwpn2,dXzzdwpn2,ns,dNpardY,dwcndY,dwpn2dY,dbetathdY)/*Doesn't have to be modified under a change of metric*/ 2463 susceptibilitytensor_format X; 2464 double complex dNperpdY[]; 2465 double complex Xxx[],Xxy[],Xxz[],Xyy[],Xyz[],Xzz[]; 2466 double complex dXxxdNperp[],dXxydNperp[],dXxzdNperp[],dXyydNperp[],dXyzdNperp[],dXzzdNperp[]; 2467 double complex dXxxdNpar[],dXxydNpar[],dXxzdNpar[],dXyydNpar[],dXyzdNpar[],dXzzdNpar[]; 2468 double complex dXxxdbetath[],dXxydbetath[],dXxzdbetath[],dXyydbetath[],dXyzdbetath[],dXzzdbetath[]; 2469 double complex dXxxdwcn[],dXxydwcn[],dXxzdwcn[],dXyydwcn[],dXyzdwcn[],dXzzdwcn[]; 2470 double complex dXxxdwpn2[],dXxydwpn2[],dXxzdwpn2[],dXyydwpn2[],dXyzdwpn2[],dXzzdwpn2[]; 2471 int ns; 2472 double dwcndY[][MC],dwpn2dY[][MC],dbetathdY[][MC],dNpardY[]; 2473 { 2474 2475 int i,is; 2476 2477 X.Xxx[0] = Xxx[0]; 2478 X.Xxy[0] = Xxy[0]; 2479 X.Xxz[0] = Xxz[0]; 2480 X.Xyy[0] = Xyy[0]; 2481 X.Xyz[0] = Xyz[0]; 2482 X.Xzz[0] = Xzz[0]; 2483 2484 for (is = 1;is < ns + 1;is++) { 2485 X.Xxx[0] = X.Xxx[0] + Xxx[is]; 2486 X.Xxy[0] = X.Xxy[0] + Xxy[is]; 2487 X.Xxz[0] = X.Xxz[0] + Xxz[is]; 2488 X.Xyy[0] = X.Xyy[0] + Xyy[is]; 2489 X.Xyz[0] = X.Xyz[0] + Xyz[is]; 2490 X.Xzz[0] = X.Xzz[0] + Xzz[is]; 2491 } 2492 2493 X.dXxxdNperp[0] = dXxxdNperp[0]; 2494 X.dXxydNperp[0] = dXxydNperp[0]; 2495 X.dXxzdNperp[0] = dXxzdNperp[0]; 2496 X.dXyydNperp[0] = dXyydNperp[0]; 2497 X.dXyzdNperp[0] = dXyzdNperp[0]; 2498 X.dXzzdNperp[0] = dXzzdNperp[0]; 2499 2500 for (is = 1;is < ns + 1;is++) { 2501 X.dXxxdNperp[0] = X.dXxxdNperp[0] + dXxxdNperp[is]; 2502 X.dXxydNperp[0] = X.dXxydNperp[0] + dXxydNperp[is]; 2503 X.dXxzdNperp[0] = X.dXxzdNperp[0] + dXxzdNperp[is]; 2504 X.dXyydNperp[0] = X.dXyydNperp[0] + dXyydNperp[is]; 2505 X.dXyzdNperp[0] = X.dXyzdNperp[0] + dXyzdNperp[is]; 2506 X.dXzzdNperp[0] = X.dXzzdNperp[0] + dXzzdNperp[is]; 2507 } 2508 2509 X.dXxxdNpar[0] = dXxxdNpar[0]; 2510 X.dXxydNpar[0] = dXxydNpar[0]; 2511 X.dXxzdNpar[0] = dXxzdNpar[0]; 2512 X.dXyydNpar[0] = dXyydNpar[0]; 2513 X.dXyzdNpar[0] = dXyzdNpar[0]; 2514 X.dXzzdNpar[0] = dXzzdNpar[0]; 2515 2516 for (is = 1;is < ns + 1;is++) { 2517 X.dXxxdNpar[0] = X.dXxxdNpar[0] + dXxxdNpar[is]; 2518 X.dXxydNpar[0] = X.dXxydNpar[0] + dXxydNpar[is]; 2519 X.dXxzdNpar[0] = X.dXxzdNpar[0] + dXxzdNpar[is]; 2520 X.dXyydNpar[0] = X.dXyydNpar[0] + dXyydNpar[is]; 2521 X.dXyzdNpar[0] = X.dXyzdNpar[0] + dXyzdNpar[is]; 2522 X.dXzzdNpar[0] = X.dXzzdNpar[0] + dXzzdNpar[is]; 2523 } 2524 2525 for (i = 0;i < MC;i++) {/* Initialisation */ 2526 X.dXxxdY[i] = 0.0; 2527 X.dXxydY[i] = 0.0; 2528 X.dXxzdY[i] = 0.0; 2529 X.dXyydY[i] = 0.0; 2530 X.dXyzdY[i] = 0.0; 2531 X.dXzzdY[i] = 0.0; 2532 } 2533 2534 2535 for (i = 0;i < MC;i++) { 2536 for (is = 0;is < ns + 1;is++) { 2537 X.dXxxdY[i] = X.dXxxdY[i] + dXxxdNperp[is]*dNperpdY[i] + dXxxdNpar[is]*dNpardY[i] + dXxxdbetath[is]*dbetathdY[is][i] + dXxxdwcn[is]*dwcndY[is][i] + dXxxdwpn2[is]*dwpn2dY[is][i]; 2538 X.dXxydY[i] = X.dXxydY[i] + dXxydNperp[is]*dNperpdY[i] + dXxydNpar[is]*dNpardY[i] + dXxydbetath[is]*dbetathdY[is][i] + dXxydwcn[is]*dwcndY[is][i] + dXxydwpn2[is]*dwpn2dY[is][i]; 2539 X.dXxzdY[i] = X.dXxzdY[i] + dXxzdNperp[is]*dNperpdY[i] + dXxzdNpar[is]*dNpardY[i] + dXxzdbetath[is]*dbetathdY[is][i] + dXxzdwcn[is]*dwcndY[is][i] + dXxzdwpn2[is]*dwpn2dY[is][i]; 2540 X.dXyydY[i] = X.dXyydY[i] + dXyydNperp[is]*dNperpdY[i] + dXyydNpar[is]*dNpardY[i] + dXyydbetath[is]*dbetathdY[is][i] + dXyydwcn[is]*dwcndY[is][i] + dXyydwpn2[is]*dwpn2dY[is][i]; 2541 X.dXyzdY[i] = X.dXyzdY[i] + dXyzdNperp[is]*dNperpdY[i] + dXyzdNpar[is]*dNpardY[i] + dXyzdbetath[is]*dbetathdY[is][i] + dXyzdwcn[is]*dwcndY[is][i] + dXyzdwpn2[is]*dwpn2dY[is][i]; 2542 X.dXzzdY[i] = X.dXzzdY[i] + dXzzdNperp[is]*dNperpdY[i] + dXzzdNpar[is]*dNpardY[i] + dXzzdbetath[is]*dbetathdY[is][i] + dXzzdwcn[is]*dwcndY[is][i] + dXzzdwpn2[is]*dwpn2dY[is][i]; 2543 } 2544 } 2545 2546 /* for (i = 0;i < MC;i++) { 2547 mexPrintf("i,dbetathdY[1][i]:%d,%g\n",i,dbetathdY[1][i]); 2548 mexPrintf("i,dwcndY[1][i]:%d,%g\n",i,dwcndY[1][i]); 2549 mexPrintf("i,dwpn2dY[1][i]:%d,%g\n",i,dwpn2dY[1][i]); 2550 mexPrintf("i,dXxxdY,dXxydY,dXxzdY,dXyydY,dXyzdY,dXzzdY:%d,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g\n",i,X.dXxxdY[i],X.dXxydY[i],X.dXxzdY[i],X.dXyydY[i],X.dXyzdY[i],X.dXzzdY[i]); 2551 mexPrintf("i,dNpardY[i],dNperpdY[i]:%d,%g,%g\n",i,dNpardY[i],dNperpdY[i]); 2552 } 2553 */ 2554 2555 } 2556 2557 2558 2559 2560 2561 void interpequil(rayparam,raymagnetic,rayprofiles,equilparam,fluctparam,Y0,Y,rayequil,rayfluctuations,flag_fluct,flag_metric)/*Has to be modified under a change of metric*/ 2562 rayparam_format rayparam; 2563 raymagnetic_format raymagnetic; 2564 rayprofiles_format rayprofiles; 2565 equilparam_format equilparam; 2566 fluctparam_format fluctparam; 2567 double Y0[],Y[]; 2568 rayequil_format rayequil; 2569 rayfluctuations_format rayfluctuations; 2570 int flag_fluct; 2571 int flag_metric; 2572 { 2573 /* interpolation from numerical equilibrium data*/ 2574 2575 double dTidY[equilparam.ns[0]],dnidY[equilparam.ns[0]]; 2576 double d2TidY2[equilparam.ns[0]],d2nidY2[equilparam.ns[0]]; 2577 double x,dxdrho,dxdtheta,d2xdtheta2,d2xdthetadrho,d2xdrho2; 2578 double y,dydrho,dydtheta,d2ydtheta2,d2ydthetadrho,d2ydrho2; 2579 double r=0,drdrho=0,drdtheta=0,d2rdtheta2=0,d2rdthetadrho=0,d2rdrho2=0; 2580 double calpha=0,dcalphadrho=0,dcalphadtheta=0,d2calphadtheta2=0,d2calphadthetadrho=0,d2calphadrho2=0; 2581 double salpha=0,dsalphadrho=0,dsalphadtheta=0,d2salphadtheta2=0,d2salphadthetadrho=0,d2salphadrho2=0; 2582 double gradrho=0,dgradrhodrho=0,dgradrhodtheta=0,d2gradrhodtheta2=0,d2gradrhodthetadrho=0,d2gradrhodrho2=0; 2583 double Bx=0,dBxdrho=0,dBxdtheta=0,d2Bxdtheta2=0,d2Bxdthetadrho=0,d2Bxdrho2=0,dBxdz=0; 2584 double By=0,dBydrho=0,dBydtheta=0,d2Bydtheta2=0,d2Bydthetadrho=0,d2Bydrho2=0,dBydz=0; 2585 double Bz=0,dBzdrho=0,dBzdtheta=0,d2Bzdtheta2=0,d2Bzdthetadrho=0,d2Bzdrho2=0,dBzdz=0; 2586 double BP=0,dBPdrho=0,dBPdtheta=0,d2BPdtheta2=0,d2BPdthetadrho=0,d2BPdrho2=0,dBPdz=0; 2587 double BB=0,dBBdrho=0,dBBdtheta=0,d2BBdtheta2=0,d2BBdthetadrho=0,d2BBdrho2=0,dBBdz=0; 2588 2589 double icm,idcmdrho,cm,cn0,dcn0drho; 2590 2591 double phaseB,dphaseBdrho,dphaseBdtheta,dphaseBdphi; 2592 double phasene,dphasenedrho,dphasenedtheta,dphasenedphi; 2593 2594 double nefsne,dnefsnedrho,dnefsnedtheta,dnefsnedphi; 2595 double TefsTe,dTefsTedrho,dTefsTedtheta,dTefsTedphi; 2596 double znifszni[equilparam.ns[0]],dznifsznidrho[equilparam.ns[0]],dznifsznidtheta[equilparam.ns[0]],dznifsznidphi[equilparam.ns[0]]; 2597 double zTifszTi[equilparam.ns[0]],dzTifszTidrho[equilparam.ns[0]],dzTifszTidtheta[equilparam.ns[0]],dzTifszTidphi[equilparam.ns[0]]; 2598 2599 double sfBx[fluctparam.B_nmodel[0]],dsfBxdrho[fluctparam.B_nmodel[0]],dsfBxdtheta[fluctparam.B_nmodel[0]],d2sfBxdtheta2[fluctparam.B_nmodel[0]],d2sfBxdthetadrho[fluctparam.B_nmodel[0]]; 2600 double sfBy[fluctparam.B_nmodel[0]],dsfBydrho[fluctparam.B_nmodel[0]],dsfBydtheta[fluctparam.B_nmodel[0]],d2sfBydtheta2[fluctparam.B_nmodel[0]],d2sfBydthetadrho[fluctparam.B_nmodel[0]]; 2601 double sfBz[fluctparam.B_nmodel[0]],dsfBzdrho[fluctparam.B_nmodel[0]],dsfBzdtheta[fluctparam.B_nmodel[0]],d2sfBzdtheta2[fluctparam.B_nmodel[0]],d2sfBzdthetadrho[fluctparam.B_nmodel[0]]; 2602 double BxfsB,dBxfsBdrho,dBxfsBdtheta,dBxfsBdphi; 2603 double ByfsB,dByfsBdrho,dByfsBdtheta,dByfsBdphi; 2604 double BzfsB,dBzfsBdrho,dBzfsBdtheta,dBzfsBdphi; 2605 double BrhofsB,dBrhofsBdrho,dBrhofsBdtheta,dBrhofsBdphi; 2606 double BsfsB,dBsfsBdrho,dBsfsBdtheta,dBsfsBdphi; 2607 double BphifsB,dBphifsBdrho,dBphifsBdtheta,dBphifsBdphi; 2608 2609 double cta,dctadrho,dctadtheta,dctadphi; 2610 double sta,dstadrho,dstadtheta,dstadphi; 2611 2612 double Brho,Bs,Bphi,B; 2613 double Brhon,Bsn,Bphin; 2614 double dBrhodrho,dBrhodtheta,dBrhodphi; 2615 double dBsdrho,dBsdtheta,dBsdphi; 2616 double dBphidrho,dBphidtheta,dBphidphi; 2617 double dBdrho,dBdtheta,dBdphi; 2618 2619 double Brho0,dBrho0drho,dBrho0dtheta; 2620 double lambda,dlambdadrho,dlambdadtheta; 2621 double rhorip,drhodrhorip,drhodthetarip,drhodphirip; 2622 2623 double val,dvaldrho,d2valdrho2; 2624 double zval[equilparam.ns[0]],dzvaldrho[equilparam.ns[0]],d2zvaldrho2[equilparam.ns[0]]; 2625 2626 double ne_sep,dnedrho_sep; 2627 double rho_neeq0; 2628 double nerip,dnedrhorip,dnedthetarip,dnedphirip; 2629 double ne_tilde,dnedrho_tilde,dnedtheta_tilde,dnedphi_tilde; 2630 double ner_tilde,dnerdrho_tilde,dnerdtheta_tilde,dnerdphi_tilde; 2631 2632 double Te_sep,dTedrho_sep; 2633 double rho_Teeq0; 2634 double Terip,dTedrhorip,dTedthetarip,dTedphirip; 2635 double Te_tilde,dTedrho_tilde,dTedtheta_tilde,dTedphi_tilde; 2636 double Ter_tilde,dTerdrho_tilde,dTerdtheta_tilde,dTerdphi_tilde; 2637 2638 double zni_sep[equilparam.ns[0]],dznidrho_sep[equilparam.ns[0]]; 2639 double rho_znieq0[equilparam.ns[0]]; 2640 double znirip[equilparam.ns[0]],dznidrhorip[equilparam.ns[0]],dznidthetarip[equilparam.ns[0]],dznidphirip[equilparam.ns[0]]; 2641 double zni_tilde[equilparam.ns[0]],dznidrho_tilde[equilparam.ns[0]],dznidtheta_tilde[equilparam.ns[0]],dznidphi_tilde[equilparam.ns[0]]; 2642 double znir_tilde[equilparam.ns[0]],dznirdrho_tilde[equilparam.ns[0]],dznirdtheta_tilde[equilparam.ns[0]],dznirdphi_tilde[equilparam.ns[0]]; 2643 2644 double zTi_sep[equilparam.ns[0]],dzTidrho_sep[equilparam.ns[0]]; 2645 double rho_zTieq0[equilparam.ns[0]]; 2646 double zTirip[equilparam.ns[0]],dzTidrhorip[equilparam.ns[0]],dzTidthetarip[equilparam.ns[0]],dzTidphirip[equilparam.ns[0]]; 2647 double zTi_tilde[equilparam.ns[0]],dzTidrho_tilde[equilparam.ns[0]],dzTidtheta_tilde[equilparam.ns[0]],dzTidphi_tilde[equilparam.ns[0]]; 2648 double zTir_tilde[equilparam.ns[0]],dzTirdrho_tilde[equilparam.ns[0]],dzTirdtheta_tilde[equilparam.ns[0]],dzTirdphi_tilde[equilparam.ns[0]]; 2649 2650 int il,im,in,iphase; 2651 2652 double dl,dm; 2653 double phase,dphasedrho,dphasedtheta,dphasedphi; 2654 double Flambda,dFlambdadrho,dFlambdadtheta,dFlambdadphi; 2655 double Fdelta,dFdeltadrho,dFdeltadtheta,dFdeltadphi; 2656 2657 double L_rho,dL_rhodrho,dL_rhodtheta,dL_rhodphi; 2658 double xq,dxqdrho,dxqdtheta,dxqdphi; 2659 double xL_theta,dxL_thetadrho,dxL_thetadtheta,dxL_thetadphi; 2660 double xL_perp,dxL_perpdrho,dxL_perpdtheta,dxL_perpdphi; 2661 double XL_phi,dXL_phidrho,dXL_phidtheta,dXL_phidphi; 2662 2663 double ac,dacdrho,dacdtheta,dacdphi; 2664 double u_l,du_ldrho,du_ldtheta,du_ldphi,expu_l,dexpu_ldrho,dexpu_ldtheta,dexpu_ldphi; 2665 double u_m,du_mdrho,du_mdtheta,du_mdphi,expu_m,dexpu_mdrho,dexpu_mdtheta,dexpu_mdphi; 2666 double u_n,du_ndrho,du_ndtheta,du_ndphi,expu_n,dexpu_ndrho,dexpu_ndtheta,dexpu_ndphi; 2667 double almn,dalmndrho,dalmndtheta,dalmndphi; 2668 double alm,dalmdrho,dalmdtheta,dalmdphi; 2669 double am,damdrho,damdtheta,damdphi; 2670 double curtheta,dcurthetadrho,dcurthetadtheta,dcurthetadphi; 2671 2672 double kperp,dkperpdrho,dkperpdtheta,dkperpdphi; 2673 2674 double ht=0,dht=0,d2ht=0; 2675 double xx=0,dxxdrho=0,dxxdtheta=0,dxxdphi=0; 2676 2677 double dummy,dummy1,dummy2,dummy3; 2678 2679 int i,j,is,imodel; 2680 2681 double save; 2682 double rho,theta,xbis,ybis; 2683 2684 /*Axisymmetric magnetic field equilibrium interpolation*/ 2685 2686 if (flag_metric == 1)/*Curvilinear case*/ 2687 { 2688 ppvald_2D(rayequil.x_fit,rayparam.dS[0],Y[0],Y[1],&x,&dxdrho,&dxdtheta,&d2xdtheta2,&d2xdthetadrho,&dummy1); 2689 2690 ppvald_2D(rayequil.y_fit,rayparam.dS[0],Y[0],Y[1],&y,&dydrho,&dydtheta,&d2ydtheta2,&d2ydthetadrho,&dummy1); 2691 ppvald_2D(rayequil.r_fit,rayparam.dS[0],Y[0],Y[1],&r,&drdrho,&drdtheta,&d2rdtheta2,&d2rdthetadrho,&dummy1); 2692 ppvald_2D(rayequil.calpha_fit,rayparam.dS[0],Y[0],Y[1],&calpha,&dcalphadrho,&dcalphadtheta,&d2calphadtheta2,&d2calphadthetadrho,&dummy1); 2693 ppvald_2D(rayequil.salpha_fit,rayparam.dS[0],Y[0],Y[1],&salpha,&dsalphadrho,&dsalphadtheta,&d2salphadtheta2,&d2salphadthetadrho,&dummy1); 2694 ppvald_2D(rayequil.gradrho_fit,rayparam.dS[0],Y[0],Y[1],&gradrho,&dgradrhodrho,&dgradrhodtheta,&d2gradrhodtheta2,&d2gradrhodthetadrho,&dummy1); 2695 2696 ppvald_2D(rayequil.Bx_fit,rayparam.dS[0],Y[0],Y[1],&Bx,&dBxdrho,&dBxdtheta,&dummy1,&dummy2,&dummy3); 2697 ppvald_2D(rayequil.By_fit,rayparam.dS[0],Y[0],Y[1],&By,&dBydrho,&dBydtheta,&dummy1,&dummy2,&dummy3); 2698 ppvald_2D(rayequil.Bz_fit,rayparam.dS[0],Y[0],Y[1],&Bz,&dBzdrho,&dBzdtheta,&dummy1,&dummy2,&dummy3); 2699 ppvald_2D(rayequil.BP_fit,rayparam.dS[0],Y[0],Y[1],&BP,&dBPdrho,&dBPdtheta,&dummy1,&dummy2,&dummy3); 2700 ppvald_2D(rayequil.B_fit,rayparam.dS[0],Y[0],Y[1],&BB,&dBBdrho,&dBBdtheta,&dummy1,&dummy2,&dummy3); 2701 2702 build_raymagnetic(Y[1],raymagnetic,equilparam,x,dxdrho,dxdtheta,d2xdtheta2,d2xdthetadrho,d2xdrho2, 2703 y,dydrho,dydtheta,d2ydtheta2,d2ydthetadrho,d2ydrho2, 2704 r,drdrho,drdtheta,d2rdtheta2,d2rdthetadrho,d2rdrho2, 2705 calpha,dcalphadrho,dcalphadtheta,d2calphadtheta2,d2calphadthetadrho,d2calphadrho2, 2706 salpha,dsalphadrho,dsalphadtheta,d2salphadtheta2,d2salphadthetadrho,d2salphadrho2, 2707 gradrho,dgradrhodrho,dgradrhodtheta,d2gradrhodtheta2,d2gradrhodthetadrho,d2gradrhodrho2, 2708 Bx,dBxdrho,dBxdtheta,d2Bxdtheta2,d2Bxdthetadrho,d2Bxdrho2,dBxdz, 2709 By,dBydrho,dBydtheta,d2Bydtheta2,d2Bydthetadrho,d2Bydrho2,dBydz, 2710 Bz,dBzdrho,dBzdtheta,d2Bzdtheta2,d2Bzdthetadrho,d2Bzdrho2,dBzdz, 2711 BP,dBPdrho,dBPdtheta,d2BPdtheta2,d2BPdthetadrho,d2BPdrho2,dBPdz, 2712 BB,dBBdrho,dBBdtheta,dBBdz,d2BBdtheta2,d2BBdthetadrho,d2BBdrho2,flag_metric); 2713 } 2714 else/*Cartesian case*/ 2715 { 2716 substitution(rayequil,rayparam,equilparam,&rho,&theta,Y);/*Retrieve (rho,theta) from (x,y) or (Y[0],Y[1]) here*/ 2717 2718 ppvald_2D(rayequil.x_fit,rayparam.dS[0],rho,theta,&x,&dxdrho,&dxdtheta,&d2xdtheta2,&d2xdthetadrho,&d2xdrho2); 2719 ppvald_2D(rayequil.y_fit,rayparam.dS[0],rho,theta,&y,&dydrho,&dydtheta,&d2ydtheta2,&d2ydthetadrho,&d2ydrho2); 2720 ppvald_2D(rayequil.r_fit,rayparam.dS[0],rho,theta,&r,&drdrho,&drdtheta,&d2rdtheta2,&d2rdthetadrho,&d2rdrho2); 2721 ppvald_2D(rayequil.calpha_fit,rayparam.dS[0],rho,theta,&calpha,&dcalphadrho,&dcalphadtheta,&d2calphadtheta2,&d2calphadthetadrho,&d2calphadrho2); 2722 ppvald_2D(rayequil.salpha_fit,rayparam.dS[0],rho,theta,&salpha,&dsalphadrho,&dsalphadtheta,&d2salphadtheta2,&d2salphadthetadrho,&d2salphadrho2); 2723 ppvald_2D(rayequil.gradrho_fit,rayparam.dS[0],rho,theta,&gradrho,&dgradrhodrho,&dgradrhodtheta,&d2gradrhodtheta2,&d2gradrhodthetadrho,&d2gradrhodrho2); 2724 2725 ppvald_2D(rayequil.Bx_fit,rayparam.dS[0],rho,theta,&Bx,&dBxdrho,&dBxdtheta,&d2Bxdtheta2,&d2Bxdthetadrho,&d2Bxdrho2); 2726 ppvald_2D(rayequil.By_fit,rayparam.dS[0],rho,theta,&By,&dBydrho,&dBydtheta,&d2Bydtheta2,&d2Bydthetadrho,&d2Bydrho2); 2727 ppvald_2D(rayequil.Bz_fit,rayparam.dS[0],rho,theta,&Bz,&dBzdrho,&dBzdtheta,&d2Bzdtheta2,&d2Bzdthetadrho,&d2Bzdrho2); 2728 ppvald_2D(rayequil.BP_fit,rayparam.dS[0],rho,theta,&BP,&dBPdrho,&dBPdtheta,&d2BPdtheta2,&d2BPdthetadrho,&d2BPdrho2); 2729 ppvald_2D(rayequil.B_fit,rayparam.dS[0],rho,theta,&BB,&dBBdrho,&dBBdtheta,&d2BBdtheta2,&d2BBdthetadrho,&d2BBdrho2); 2730 2731 build_raymagnetic(theta,raymagnetic,equilparam,x,dxdrho,dxdtheta,d2xdtheta2,d2xdthetadrho,d2xdrho2, 2732 y,dydrho,dydtheta,d2ydtheta2,d2ydthetadrho,d2ydrho2, 2733 r,drdrho,drdtheta,d2rdtheta2,d2rdthetadrho,d2rdrho2, 2734 calpha,dcalphadrho,dcalphadtheta,d2calphadtheta2,d2calphadthetadrho,d2calphadrho2, 2735 salpha,dsalphadrho,dsalphadtheta,d2salphadtheta2,d2salphadthetadrho,d2salphadrho2, 2736 gradrho,dgradrhodrho,dgradrhodtheta,d2gradrhodtheta2,d2gradrhodthetadrho,d2gradrhodrho2, 2737 Bx,dBxdrho,dBxdtheta,d2Bxdtheta2,d2Bxdthetadrho,d2Bxdrho2,dBxdz, 2738 By,dBydrho,dBydtheta,d2Bydtheta2,d2Bydthetadrho,d2Bydrho2,dBydz, 2739 Bz,dBzdrho,dBzdtheta,d2Bzdtheta2,d2Bzdthetadrho,d2Bzdrho2,dBzdz, 2740 BP,dBPdrho,dBPdtheta,d2BPdtheta2,d2BPdthetadrho,d2BPdrho2,dBPdz, 2741 BB,dBBdrho,dBBdtheta,d2BBdtheta2,d2BBdthetadrho,d2BBdrho2,dBBdz,flag_metric); 2742 } 2743 2744 /*Definition of the derivatives used to defined the cartesian derivatives*/ 2745 2746 double calpha_theta = calpha*cos(theta) + salpha*sin(theta);/*cos(alpha-theta)*/ 2747 double salpha_theta = salpha*cos(theta) - calpha*sin(theta);/*sin(alpha-theta)*/ 2748 2749 double drhodx = gradrho*equilparam.ap[0]*calpha_theta;/*drhodx for the change of variable (rho,theta)->(x,y)*/ 2750 double drhody = -gradrho*equilparam.ap[0]*salpha_theta;/*drhody for the change of variable (rho,theta)->(x,y)*/ 2751 double dthetadx = -sin(theta)*equilparam.ap[0]/r;/*dthetadx for the change of variable (rho,theta)->(x,y)*/ 2752 double dthetady = cos(theta)*equilparam.ap[0]/r;/*dthetady for the change of variable (rho,theta)->(x,y)*/ 2753 2754 double dxdrhobis = cos(theta)/(calpha*raymagnetic.gradrhon[0]);/*dxdrho for the change of variable (x,y)->(rho,theta)*/ 2755 double dydrhobis = sin(theta)/(calpha*raymagnetic.gradrhon[0]);/*dydrho for the change of variable (x,y)->(rho,theta)*/ 2756 double dxdthetabis = raymagnetic.rn[0]*salpha_theta/calpha;/*dxdtheta for the change of variable (x,y)->(rho,theta)*/ 2757 double dydthetabis = raymagnetic.rn[0]*calpha_theta/calpha;/*dydtheta for the change of variable (x,y)->(rho,theta)*/ 2758 2759 if (equilparam.zZi[0] > 0) { /*Plasma case, otherwise vacuum*/ 2760 2761 if (flag_metric == 1) 2762 { 2763 2764 ppvald_1D(rayequil.Te_fit,rayparam.dS[0],Y[0],&rayprofiles.Te[0],&rayprofiles.dTedY[0],&rayprofiles.d2TedY2[0]); 2765 2766 rayprofiles.dTedY[1] = 0;/*Te is taken constant on a magnetic flux surface*/ 2767 rayprofiles.dTedY[2] = 0;/*Te is taken constant on a magnetic flux surface*/ 2768 2769 ppvald_1D(rayequil.ne_fit,rayparam.dS[0],Y[0],&rayprofiles.ne[0],&rayprofiles.dnedY[0],&rayprofiles.d2nedY2[0]); 2770 rayprofiles.dnedY[1] = 0;/*ne is taken constant on a magnetic flux surface*/ 2771 rayprofiles.dnedY[2] = 0;/*ne is taken constant on a magnetic flux surface*/ 2772 2773 /*mexPrintf("Y[0],Y[1],Y[2],ne[0]:%g,%g,%g,%g\n",Y[0],Y[1],Y[2],rayprofiles.ne[0]);*/ 2774 2775 ppvald_1D(rayequil.zTi_fit,rayparam.dS[0],Y[0],rayprofiles.zTi,dTidY,d2TidY2); 2776 ppvald_1D(rayequil.zni_fit,rayparam.dS[0],Y[0],rayprofiles.zni,dnidY,d2nidY2); 2777 2778 for (is=0;is /*ni is taken constant on a magnetic flux surface*/ 2782 rayprofiles.dzTidY[is][2] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2783 rayprofiles.d2zTidY2[is][0] = d2TidY2[is]; 2784 rayprofiles.d2zTidY2[is][1] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2785 rayprofiles.d2zTidY2[is][2] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2786 2787 rayprofiles.dznidY[is][0] = dnidY[is]; 2788 rayprofiles.dznidY[is][1] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2789 rayprofiles.dznidY[is][2] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2790 rayprofiles.d2znidY2[is][0] = d2nidY2[is]; 2791 rayprofiles.d2znidY2[is][1] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2792 rayprofiles.d2znidY2[is][2] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2793 } 2794 } 2795 else 2796 { 2797 ppvald_1D(rayequil.Te_fit,rayparam.dS[0],rho,&rayprofiles.Te[0],&rayprofiles.dTedY[0],&rayprofiles.d2TedY2[0]); 2798 save = rayprofiles.dTedY[0]; 2799 rayprofiles.dTedY[0] = save*drhodx; 2800 rayprofiles.dTedY[1] = save*drhody; 2801 rayprofiles.dTedY[2] = 0;/*Te is taken constant on a magnetic flux surface*/ 2802 2803 ppvald_1D(rayequil.ne_fit,rayparam.dS[0],rho,&rayprofiles.ne[0],&rayprofiles.dnedY[0],&rayprofiles.d2nedY2[0]); 2804 save = rayprofiles.dnedY[0]; 2805 rayprofiles.dnedY[0] = save*drhodx; 2806 rayprofiles.dnedY[1] = save*drhody; 2807 rayprofiles.dnedY[2] = 0;/*Te is taken constant on a magnetic flux surface*/ 2808 2809 /*mexPrintf("Y[0],Y[1],Y[2],ne[0]:%g,%g,%g,%g\n",Y[0],Y[1],Y[2],rayprofiles.ne[0]);*/ 2810 2811 ppvald_1D(rayequil.zTi_fit,rayparam.dS[0],rho,rayprofiles.zTi,dTidY,d2TidY2); 2812 ppvald_1D(rayequil.zni_fit,rayparam.dS[0],rho,rayprofiles.zni,dnidY,d2nidY2); 2813 2814 for (is=0;is /*ni is taken constant on a magnetic flux surface*/ 2820 rayprofiles.d2zTidY2[is][0] = d2TidY2[is]; 2821 rayprofiles.d2zTidY2[is][1] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2822 rayprofiles.d2zTidY2[is][2] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2823 2824 save = dnidY[is]; 2825 rayprofiles.dznidY[is][0] = save*drhodx; 2826 rayprofiles.dznidY[is][1] = save*drhody; 2827 rayprofiles.dznidY[is][2] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2828 rayprofiles.d2znidY2[is][0] = d2nidY2[is]; 2829 rayprofiles.d2znidY2[is][1] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2830 rayprofiles.d2znidY2[is][2] = 0.0;/*ni is taken constant on a magnetic flux surface*/ 2831 } 2832 } 2833 2834 /*--------------------------------------------------------------------------*/ 2835 /*---------------------Contribution of the fluctuations --------------------*/ 2836 /*--------------------------------------------------------------------------*/ 2837 2838 if (flag_fluct == 1) { /* no fluctuation in vacuum */ 2839 2840 /*Initialisation of the perturbations */ 2841 2842 if(flag_metric == 2)/*All fluctuations calculations will be done in flux coordinates to avoid having to drastically modify this part of the code, the final values will be translated in cartesian coordinates at the end*/ 2843 { 2844 xbis = Y[0]; 2845 ybis = Y[1]; 2846 Y[0] = rho; 2847 Y[1] = theta; 2848 2849 save = raymagnetic.drndY[0]; 2850 raymagnetic.drndY[0] = dxdrhobis*raymagnetic.drndY[0] + dydrhobis*raymagnetic.drndY[1]; 2851 raymagnetic.drndY[1] = dxdthetabis*save + dydthetabis*raymagnetic.drndY[1]; 2852 2853 save = raymagnetic.dxndY[0]; 2854 raymagnetic.dxndY[0] = dxdrhobis*raymagnetic.dxndY[0] + dydrhobis*raymagnetic.dxndY[1]; 2855 raymagnetic.dxndY[1] = dxdthetabis*save + dydthetabis*raymagnetic.dxndY[1]; 2856 2857 save = raymagnetic.dyndY[0]; 2858 raymagnetic.dyndY[0] = dxdrhobis*raymagnetic.dyndY[0] + dydrhobis*raymagnetic.dyndY[1]; 2859 raymagnetic.dyndY[1] = dxdthetabis*save + dydthetabis*raymagnetic.dyndY[1]; 2860 2861 save = raymagnetic.dBrhondY[0]; 2862 raymagnetic.dBrhondY[0] = dxdrhobis*raymagnetic.dBrhondY[0] + dydrhobis*raymagnetic.dBrhondY[1]; 2863 raymagnetic.dBrhondY[1] = dxdthetabis*save + dydthetabis*raymagnetic.dBrhondY[1]; 2864 2865 save = raymagnetic.dBsndY[0]; 2866 raymagnetic.dBsndY[0] = dxdrhobis*raymagnetic.dBsndY[0] + dydrhobis*raymagnetic.dBsndY[1]; 2867 raymagnetic.dBsndY[1] = dxdthetabis*save + dydthetabis*raymagnetic.dBsndY[1]; 2868 2869 save = raymagnetic.dBzndY[0]; 2870 raymagnetic.dBzndY[0] = dxdrhobis*raymagnetic.dBzndY[0] + dydrhobis*raymagnetic.dBzndY[1]; 2871 raymagnetic.dBzndY[1] = dxdthetabis*save + dydthetabis*raymagnetic.dBzndY[1]; 2872 2873 save = raymagnetic.dBdY[0]; 2874 raymagnetic.dBdY[0] = dxdrhobis*raymagnetic.dBdY[0] + dydrhobis*raymagnetic.dBdY[1]; 2875 raymagnetic.dBdY[1] = dxdthetabis*save + dydthetabis*raymagnetic.dBdY[1]; 2876 2877 save = raymagnetic.dsalphadY[0]; 2878 raymagnetic.dsalphadY[0] = dxdrhobis*raymagnetic.dsalphadY[0] + dydrhobis*raymagnetic.dsalphadY[1]; 2879 raymagnetic.dsalphadY[1] = dxdthetabis*save + dydthetabis*raymagnetic.dsalphadY[1]; 2880 2881 save = raymagnetic.dcalphadY[0]; 2882 raymagnetic.dcalphadY[0] = dxdrhobis*raymagnetic.dcalphadY[0] + dydrhobis*raymagnetic.dcalphadY[1]; 2883 raymagnetic.dcalphadY[1] = dxdthetabis*save + dydthetabis*raymagnetic.dcalphadY[1]; 2884 2885 save = raymagnetic.dgradrhondY[0]; 2886 raymagnetic.dgradrhondY[0] = dxdrhobis*raymagnetic.dgradrhondY[0] + dydrhobis*raymagnetic.dgradrhondY[1]; 2887 raymagnetic.dgradrhondY[1] = dxdthetabis*save + dydthetabis*raymagnetic.dgradrhondY[1]; 2888 2889 save = raymagnetic.drhoripdY[0]; 2890 raymagnetic.drhoripdY[0] = dxdrhobis*raymagnetic.drhoripdY[0] + dydrhobis*raymagnetic.drhoripdY[1]; 2891 raymagnetic.drhoripdY[1] = dxdthetabis*save + dydthetabis*raymagnetic.drhoripdY[1]; 2892 2893 save = raymagnetic.dUpsilonndY[0]; 2894 raymagnetic.dUpsilonndY[0] = dxdrhobis*raymagnetic.dUpsilonndY[0] + dydrhobis*raymagnetic.dUpsilonndY[1]; 2895 raymagnetic.dUpsilonndY[1] = dxdthetabis*save + dydthetabis*raymagnetic.dUpsilonndY[1]; 2896 2897 save = rayprofiles.dTedY[0]; 2898 rayprofiles.dTedY[0] = dxdrhobis*rayprofiles.dTedY[0] + dydrhobis*rayprofiles.dTedY[1]; 2899 rayprofiles.dTedY[1] = dxdthetabis*save + dydthetabis*rayprofiles.dTedY[1]; 2900 2901 save = rayprofiles.dnedY[0]; 2902 rayprofiles.dnedY[0] = dxdrhobis*rayprofiles.dnedY[0] + dydrhobis*rayprofiles.dnedY[1]; 2903 rayprofiles.dnedY[1] = dxdthetabis*save + dydthetabis*rayprofiles.dnedY[1]; 2904 2905 for(is=0;is for (is=0;is /*geometrical factor for fluctuations phase, kpar = 0 drift wave model */ 2981 ppvald_2D(rayfluctuations.Xcm_fit,rayparam.dS[0],Y[0],Y[1],&cm,&dummy,&dummy,&dummy,&dummy);/*geometrical factor for fluctuations phase, kpar = 0 drift wave model */ 2982 ppvali_2D(rayfluctuations.Xcm_fit,rayparam.dS[0],Y[0],Y0[1],Y[1],&icm,&idcmdrho);/*geometrical factor for fluctuations phase, kpar = 0 drift wave model */ 2983 2984 /* 2985 mexPrintf("rho,theta,phi,gphase,dgphasedrho,dgphasedtheta,dgphasedphi:%g,%g,%g,%g,%g,%g,%g\n",Y[0],Y[1],Y[2],gphase,dgphasedrho,dgphasedtheta,dgphasedphi); 2986 mexPrintf("cn0,dcn0drho,icm,idcmdrho,cm:%g,%g,%g,%g,%g\n",cn0,dcn0drho,icm,idcmdrho,cm); 2987 */ 2988 2989 if (fluctparam.ne_nmodel[0] > 0) {/* Electron density statistical fluctuations */ 2990 2991 for (imodel=0; imodel < fluctparam.ne_nmodel[0]; imodel++) { 2992 2993 dl = fluctparam.ne_lmax[imodel][0] - fluctparam.ne_lmin[imodel][0] + 1.0; 2994 dm = fluctparam.ne_mmax[imodel][0] - fluctparam.ne_mmin[imodel][0] + 1.0; 2995 2996 Flambda = (1.0 + fluctparam.ne_polmode[imodel][0] + (1.0 - fluctparam.ne_polmode[imodel][0])*cos(Y[1]))/2.0; 2997 dFlambdadrho = 0.0; 2998 dFlambdadtheta = -(1.0 - fluctparam.ne_polmode[imodel][0])*sin(Y[1])/2.0; 2999 dFlambdadphi = 0.0; 3000 3001 Fdelta = exp(-log(2.0)*pow(Y[0] - fluctparam.ne_sigmar_rho[imodel][0],2.0)/pow(fluctparam.ne_sigmar_hwhm[imodel][0],2)); 3002 dFdeltadrho = -Fdelta*2.0*log(2.0)*(Y[0] - fluctparam.ne_sigmar_rho[imodel][0])/pow(fluctparam.ne_sigmar_hwhm[imodel][0],2); 3003 dFdeltadtheta = 0.0; 3004 dFdeltadphi = 0.0; 3005 3006 xx = 0; 3007 dxxdrho = 0; 3008 dxxdtheta = 0; 3009 dxxdphi = 0; 3010 3011 if (fluctparam.ne_model[imodel][0] == 1) {/* 3-D Gaussian model (rho,theta,phi), relative epsi values (benchmark of C3PO) */ 3012 3013 ac = 4.0*pow(PI,0.75)*fluctparam.ne_sigmar_max[imodel][0]*sqrt(fluctparam.ne_epsi_rho[imodel][0]*fluctparam.ne_epsi_theta[imodel][0]*fluctparam.ne_epsi_phi[imodel][0]); 3014 3015 for (il = fluctparam.ne_lmin[imodel][0];il <= fluctparam.ne_lmax[imodel][0];il++) { 3016 for (im = fluctparam.ne_mmin[imodel][0];im <= fluctparam.ne_mmax[imodel][0];im++) { 3017 for (in = fluctparam.ne_nmin[imodel][0];in <= fluctparam.ne_nmax[imodel][0];in++) { 3018 3019 iphase = (int)dl*(int)dm*(in-(int)fluctparam.ne_nmin[imodel][0]) + (int)dl*(im-(int)fluctparam.ne_mmin[imodel][0]) + (il-(int)fluctparam.ne_lmin[imodel][0]) + 1; 3020 3021 phase = 2*PI*il*Y[0] + im*Y[1] + in*Y[2]/equilparam.Rp[0] + fluctparam.ne_phase[imodel][iphase-1]; 3022 dphasedrho = 2*PI*il; 3023 dphasedtheta = im; 3024 dphasedphi = in; 3025 3026 u_l = PI*fluctparam.ne_epsi_rho[imodel][0]*il; 3027 u_m = PI*fluctparam.ne_epsi_theta[imodel][0]*im; 3028 u_n = PI*fluctparam.ne_epsi_phi[imodel][0]*in; 3029 3030 expu_l = exp(-u_l*u_l/2); 3031 expu_m = exp(-u_m*u_m/2); 3032 expu_n = exp(-u_n*u_n/2); 3033 3034 almn = expu_l*expu_m*expu_n; 3035 3036 xx += ac*almn*Flambda*Fdelta*sin(phase); 3037 dxxdrho += ac*almn*Flambda*(Fdelta*cos(phase)*dphasedrho + dFdeltadrho*sin(phase)); 3038 dxxdtheta += ac*almn*Fdelta*(Flambda*cos(phase)*dphasedtheta + dFlambdadtheta*sin(phase)); 3039 dxxdphi += ac*almn*Flambda*Fdelta*cos(phase)*dphasedphi; 3040 } 3041 } 3042 } 3043 3044 /* convolution to avoid negative density values. No restriction on positive values, ht(x) = x */ 3045 3046 halftanh(xx,&ht,&dht,&d2ht); 3047 3048 nefsne += ht; 3049 dnefsnedrho += dht*dxxdrho; 3050 dnefsnedtheta += dht*dxxdtheta; 3051 dnefsnedphi += dht*dxxdphi; 3052 3053 } 3054 3055 if (fluctparam.ne_model[imodel][0] == 2) {/* 3-D Gaussian model (rho,theta,phi), absolute epsi values (benchmark of C3PO) */ 3056 3057 ac = 4.0*pow(PI,0.75)*fluctparam.ne_sigmar_max[imodel][0]*sqrt(fluctparam.ne_epsi_rho[imodel][0]*fluctparam.ne_epsi_theta[imodel][0]*fluctparam.ne_epsi_phi[imodel][0]/L_rho/xL_theta/XL_phi); 3058 dacdrho = -0.5*ac*(dL_rhodrho/L_rho + dxL_thetadrho/xL_theta + dXL_phidrho/XL_phi); 3059 dacdtheta = -0.5*ac*(dL_rhodtheta/L_rho + dxL_thetadtheta/xL_theta + dXL_phidtheta/XL_phi); 3060 dacdphi = -0.5*ac*(dL_rhodphi/L_rho + dxL_thetadphi/xL_theta + dXL_phidphi/XL_phi); 3061 3062 for (il = fluctparam.ne_lmin[imodel][0];il <= fluctparam.ne_lmax[imodel][0];il++) { 3063 for (im = fluctparam.ne_mmin[imodel][0];im <= fluctparam.ne_mmax[imodel][0];im++) { 3064 for (in = fluctparam.ne_nmin[imodel][0];in <= fluctparam.ne_nmax[imodel][0];in++) { 3065 3066 iphase = (int)dl*(int)dm*(in-(int)fluctparam.ne_nmin[imodel][0]) + (int)dl*(im-(int)fluctparam.ne_mmin[imodel][0]) + (il-(int)fluctparam.ne_lmin[imodel][0]) + 1; 3067 3068 phase = 2*PI*il*Y[0] + im*Y[1] + in*Y[2]/equilparam.Rp[0] + fluctparam.ne_phase[imodel][iphase-1]; 3069 dphasedrho = 2*PI*il; 3070 dphasedtheta = im; 3071 dphasedphi = in; 3072 3073 u_l = PI*fluctparam.ne_epsi_rho[imodel][0]*il/L_rho; 3074 u_m = PI*fluctparam.ne_epsi_theta[imodel][0]*im/xL_theta; 3075 u_n = PI*fluctparam.ne_epsi_phi[imodel][0]*in/XL_phi; 3076 3077 du_ldrho = -u_l/L_rho*dL_rhodrho; 3078 du_mdrho = -u_m/xL_theta*dxL_thetadrho; 3079 du_ndrho = -u_n/XL_phi*dXL_phidrho; 3080 3081 du_ldtheta = -u_l/L_rho*dL_rhodtheta; 3082 du_mdtheta = -u_m/xL_theta*dxL_thetadtheta; 3083 du_ndtheta = -u_n/XL_phi*dXL_phidtheta; 3084 3085 du_ldphi = -u_l/L_rho*dL_rhodphi; 3086 du_mdphi = -u_m/xL_theta*dxL_thetadphi; 3087 du_ndphi = -u_n/XL_phi*dXL_phidphi; 3088 3089 expu_l = exp(-u_l*u_l/2); 3090 expu_m = exp(-u_m*u_m/2); 3091 expu_n = exp(-u_n*u_n/2); 3092 almn = expu_l*expu_m*expu_n; 3093 3094 dexpu_ldrho = -expu_l*u_l*du_ldrho; 3095 dexpu_mdrho = -expu_m*u_m*du_mdrho; 3096 dexpu_ndrho = -expu_n*u_n*du_ndrho; 3097 dalmndrho = dexpu_ldrho*expu_m*expu_n + expu_l*dexpu_mdrho*expu_n + expu_l*expu_m*dexpu_ndrho; 3098 3099 dexpu_ldtheta = -expu_l*u_l*du_ldtheta; 3100 dexpu_mdtheta = -expu_m*u_m*du_mdtheta; 3101 dexpu_ndtheta = -expu_n*u_n*du_ndtheta; 3102 dalmndtheta = dexpu_ldtheta*expu_m*expu_n + expu_l*dexpu_mdtheta*expu_n + expu_l*expu_m*dexpu_ndtheta; 3103 3104 dexpu_ldphi = -expu_l*u_l*du_ldphi; 3105 dexpu_mdphi = -expu_m*u_m*du_mdphi; 3106 dexpu_ndphi = -expu_n*u_n*du_ndphi; 3107 dalmndphi = dexpu_ldphi*expu_m*expu_n + expu_l*dexpu_mdphi*expu_n + expu_l*expu_m*dexpu_ndphi; 3108 3109 xx += ac*Flambda*Fdelta*almn*sin(phase); 3110 dxxdrho += dacdrho*Flambda*Fdelta*almn*sin(phase) + ac*dFlambdadrho*Fdelta*almn*sin(phase) + ac*Flambda*dFdeltadrho*almn*sin(phase) + ac*Flambda*Fdelta*dalmndrho*sin(phase) + ac*Flambda*Fdelta*almn*cos(phase)*dphasedrho; 3111 dxxdtheta += dacdtheta*Flambda*Fdelta*almn*sin(phase) + ac*dFlambdadtheta*Fdelta*almn*sin(phase) + ac*Flambda*dFdeltadtheta*almn*sin(phase) + ac*Flambda*Fdelta*dalmndtheta*sin(phase) + ac*Flambda*Fdelta*almn*cos(phase)*dphasedtheta; 3112 dxxdphi += dacdphi*Flambda*Fdelta*almn*sin(phase) + ac*dFlambdadphi*Fdelta*almn*sin(phase) + ac*Flambda*dFdeltadphi*almn*sin(phase) + ac*Flambda*Fdelta*dalmndphi*sin(phase) + ac*Flambda*Fdelta*almn*cos(phase)*dphasedphi; 3113 } 3114 } 3115 } 3116 3117 /* convolution to avoid negative density values. No restriction on positive values, ht(x) = x */ 3118 3119 halftanh(xx,&ht,&dht,&d2ht); 3120 3121 nefsne += ht; 3122 dnefsnedrho += dht*dxxdrho; 3123 dnefsnedtheta += dht*dxxdtheta; 3124 dnefsnedphi += dht*dxxdphi; 3125 } 3126 3127 if (fluctparam.ne_model[imodel][0] == 3) {/* 2-D Gaussian model (rho,curtheta), absolute epsi values (drift wave model, global cylindrical phase approx.) */ 3128 3129 /* Note that epsi_perp = fluctparam.ne_epsi_theta */ 3130 3131 ac = 2.0*sqrt(2.0*PI)*fluctparam.ne_sigmar_max[imodel][0]*sqrt(fluctparam.ne_epsi_rho[imodel][0]*fluctparam.ne_epsi_theta[imodel][0]/L_rho/xL_perp); 3132 dacdrho = -0.5*ac*(dL_rhodrho/L_rho + dxL_perpdrho/xL_perp); 3133 dacdtheta = -0.5*ac*(dL_rhodtheta/L_rho + dxL_perpdtheta/xL_perp); 3134 dacdphi = -0.5*ac*(dL_rhodphi/L_rho + dxL_perpdphi/xL_perp); 3135 3136 for (il = fluctparam.ne_lmin[imodel][0];il <= fluctparam.ne_lmax[imodel][0];il++) { 3137 for (im = fluctparam.ne_mmin[imodel][0];im <= fluctparam.ne_mmax[imodel][0];im++) { 3138 3139 iphase = (int)dl*(im-(int)fluctparam.ne_mmin[imodel][0]) + (il-(int)fluctparam.ne_lmin[imodel][0]) + 1; 3140 3141 curtheta = xq*Y[1] - Y[2]/equilparam.Rp[0]; 3142 dcurthetadrho = dxqdrho*Y[1]; 3143 dcurthetadtheta = dxqdtheta*Y[1] + xq; 3144 dcurthetadphi = dxqdphi*Y[1]-1.0; 3145 3146 phase = 2*PI*il*Y[0] + im*curtheta + fluctparam.ne_phase[imodel][iphase-1]; 3147 dphasedrho = 2*PI*il + im*dcurthetadrho; 3148 dphasedtheta = im*dcurthetadtheta; 3149 dphasedphi = im*dcurthetadphi; 3150 3151 u_l = PI*fluctparam.ne_epsi_rho[imodel][0]*il/L_rho; 3152 u_m = PI*fluctparam.ne_epsi_theta[imodel][0]*im/xL_perp; 3153 3154 du_ldrho = -u_l/L_rho*dL_rhodrho; 3155 du_mdrho = -u_m/xL_perp*dxL_perpdrho; 3156 3157 du_ldtheta = -u_l/L_rho*dL_rhodtheta; 3158 du_mdtheta = -u_m/xL_perp*dxL_perpdtheta; 3159 3160 du_ldphi = -u_l/L_rho*dL_rhodphi; 3161 du_mdphi = -u_m/xL_perp*dxL_perpdphi; 3162 3163 expu_l = exp(-u_l*u_l/2); 3164 expu_m = exp(-u_m*u_m/2); 3165 alm = expu_l*expu_m; 3166 3167 dexpu_ldrho = -expu_l*u_l*du_ldrho; 3168 dexpu_mdrho = -expu_m*u_m*du_mdrho; 3169 dalmdrho = dexpu_ldrho*expu_m + expu_l*dexpu_mdrho; 3170 3171 dexpu_ldtheta = -expu_l*u_l*du_ldtheta; 3172 dexpu_mdtheta = -expu_m*u_m*du_mdtheta; 3173 dalmdtheta = dexpu_ldtheta*expu_m + expu_l*dexpu_mdtheta; 3174 3175 dexpu_ldphi = -expu_l*u_l*du_ldphi; 3176 dexpu_mdphi = -expu_m*u_m*du_mdphi; 3177 dalmdphi = dexpu_ldphi*expu_m + expu_l*dexpu_mdphi; 3178 3179 xx += ac*Flambda*Fdelta*alm*sin(phase); 3180 dxxdrho += dacdrho*Flambda*Fdelta*alm*sin(phase) + ac*dFlambdadrho*Fdelta*alm*sin(phase) + ac*Flambda*dFdeltadrho*alm*sin(phase) + ac*Flambda*Fdelta*dalmdrho*sin(phase) + ac*Flambda*Fdelta*alm*cos(phase)*dphasedrho; 3181 dxxdtheta += dacdtheta*Flambda*Fdelta*alm*sin(phase) + ac*dFlambdadtheta*Fdelta*alm*sin(phase) + ac*Flambda*dFdeltadtheta*alm*sin(phase) + ac*Flambda*Fdelta*dalmdtheta*sin(phase) + ac*Flambda*Fdelta*alm*cos(phase)*dphasedtheta; 3182 dxxdphi += dacdphi*Flambda*Fdelta*alm*sin(phase) + ac*dFlambdadphi*Fdelta*alm*sin(phase) + ac*Flambda*dFdeltadphi*alm*sin(phase) + ac*Flambda*Fdelta*dalmdphi*sin(phase) + ac*Flambda*Fdelta*alm*cos(phase)*dphasedphi; 3183 3184 } 3185 } 3186 3187 /* convolution to avoid negative density values. No restriction on positive values, ht(x) = x */ 3188 3189 halftanh(xx,&ht,&dht,&d2ht); 3190 3191 nefsne += ht; 3192 dnefsnedrho += dht*dxxdrho; 3193 dnefsnedtheta += dht*dxxdtheta; 3194 dnefsnedphi += dht*dxxdphi; 3195 } 3196 3197 if (fluctparam.ne_model[imodel][0] == 4) {/* 1-D Gaussian model (rho,curtheta), absolute epsi values (drift wave model, global cylindrical phase approx.) */ 3198 3199 /* Note that epsi_perp = fluctparam.ne_epsi_theta */ 3200 3201 ac = 2.0*sqrt(sqrt(PI))*fluctparam.ne_sigmar_max[imodel][0]*sqrt(fluctparam.ne_epsi_theta[imodel][0]/xL_perp); 3202 dacdrho = -0.5*ac*dxL_perpdrho/xL_perp; 3203 dacdtheta = -0.5*ac*dxL_perpdtheta/xL_perp; 3204 dacdphi = -0.5*ac*dxL_perpdphi/xL_perp; 3205 3206 for (im = fluctparam.ne_mmin[imodel][0];im <= fluctparam.ne_mmax[imodel][0];im++) { 3207 3208 iphase = (im-(int)fluctparam.ne_mmin[imodel][0]) + 1; 3209 3210 curtheta = xq*(Y[1] - Y0[1]) - (Y[2] - Y0[2])/equilparam.Rp[0]; 3211 dcurthetadrho = dxqdrho*(Y[1] - Y0[1]); 3212 dcurthetadtheta = dxqdtheta*Y[1] + xq; 3213 dcurthetadphi = dxqdphi*Y[1] - 1.0; 3214 3215 phase = im*curtheta + fluctparam.ne_phase[imodel][iphase-1]; 3216 dphasedrho = im*dcurthetadrho; 3217 dphasedtheta = im*dcurthetadtheta; 3218 dphasedphi = im*dcurthetadphi; 3219 3220 u_m = PI*fluctparam.ne_epsi_theta[imodel][0]*im/xL_perp; 3221 3222 du_mdrho = -u_m/xL_perp*dxL_perpdrho; 3223 3224 du_mdtheta = -u_m/xL_perp*dxL_perpdtheta; 3225 3226 du_mdphi = -u_m/xL_perp*dxL_perpdphi; 3227 3228 expu_m = exp(-u_m*u_m/2); 3229 am = expu_m; 3230 3231 damdrho = -expu_m*u_m*du_mdrho; 3232 3233 damdtheta = -expu_m*u_m*du_mdtheta; 3234 3235 damdphi = -expu_m*u_m*du_mdphi; 3236 3237 xx += ac*Flambda*Fdelta*am*sin(phase); 3238 dxxdrho += dacdrho*Flambda*Fdelta*am*sin(phase) + ac*dFlambdadrho*Fdelta*am*sin(phase) + ac*Flambda*dFdeltadrho*am*sin(phase) + ac*Flambda*Fdelta*damdrho*sin(phase) + ac*Flambda*Fdelta*am*cos(phase)*dphasedrho; 3239 dxxdtheta += dacdtheta*Flambda*Fdelta*am*sin(phase) + ac*dFlambdadtheta*Fdelta*am*sin(phase) + ac*Flambda*dFdeltadtheta*am*sin(phase) + ac*Flambda*Fdelta*damdtheta*sin(phase) + ac*Flambda*Fdelta*am*cos(phase)*dphasedtheta; 3240 dxxdphi += dacdphi*Flambda*Fdelta*am*sin(phase) + ac*dFlambdadphi*Fdelta*am*sin(phase) + ac*Flambda*dFdeltadphi*am*sin(phase) + ac*Flambda*Fdelta*damdphi*sin(phase) + ac*Flambda*Fdelta*am*cos(phase)*dphasedphi; 3241 3242 } 3243 3244 /* convolution to avoid negative density values. No restriction on positive values, ht(x) = x */ 3245 3246 3247 halftanh(xx,&ht,&dht,&d2ht); 3248 3249 nefsne += ht; 3250 dnefsnedrho += dht*dxxdrho; 3251 dnefsnedtheta += dht*dxxdtheta; 3252 dnefsnedphi += dht*dxxdphi; 3253 } 3254 3255 3256 if (fluctparam.ne_model[imodel][0] == 5) {/* 1-D Gaussian model (rho,cm,cn), absolute epsi values (drift wave model, local phase approx. ) */ 3257 3258 /* Note that epsi_perp = fluctparam.ne_epsi_theta */ 3259 3260 ac = 2.0*sqrt(sqrt(PI))*fluctparam.ne_sigmar_max[imodel][0]*sqrt(fluctparam.ne_epsi_theta[imodel][0]/xL_perp); 3261 dacdrho = -0.5*ac*dxL_perpdrho/xL_perp; 3262 dacdtheta = -0.5*ac*dxL_perpdtheta/xL_perp; 3263 dacdphi = -0.5*ac*dxL_perpdphi/xL_perp; 3264 3265 for (im = fluctparam.ne_mmin[imodel][0];im <= fluctparam.ne_mmax[imodel][0];im++) { 3266 3267 iphase = (im-(int)fluctparam.ne_mmin[imodel][0]) + 1; 3268 3269 kperp = 2*PI*im/xL_perp; 3270 dkperpdrho = -kperp/xL_perp*dxL_perpdrho;; 3271 dkperpdtheta = 0.0; 3272 dkperpdphi = 0.0; 3273 3274 phase = (icm + cn0*(Y[2] - Y0[2])/equilparam.Rp[0])*kperp + fluctparam.ne_phase[imodel][iphase-1]; 3275 dphasedrho = (idcmdrho + dcn0drho*(Y[2] - Y0[2])/equilparam.Rp[0])*kperp + (icm + cn0*(Y[2] - Y0[2])/equilparam.Rp[0])*dkperpdrho; 3276 dphasedtheta = cm*kperp + (icm + cn0*(Y[2] - Y0[2])/equilparam.Rp[0])*dkperpdtheta; 3277 dphasedphi = cn0*kperp + (icm + cn0*(Y[2] - Y0[2])/equilparam.Rp[0])*dkperpdphi; 3278 3279 u_m = PI*fluctparam.ne_epsi_theta[imodel][0]*im/xL_perp; 3280 3281 du_mdrho = -u_m/xL_perp*dxL_perpdrho; 3282 3283 du_mdtheta = -u_m/xL_perp*dxL_perpdtheta; 3284 3285 du_mdphi = -u_m/xL_perp*dxL_perpdphi; 3286 3287 expu_m = exp(-u_m*u_m/2); 3288 am = expu_m; 3289 3290 damdrho = -expu_m*u_m*du_mdrho; 3291 3292 damdtheta = -expu_m*u_m*du_mdtheta; 3293 3294 damdphi = -expu_m*u_m*du_mdphi; 3295 3296 xx += ac*Flambda*Fdelta*am*sin(phase); 3297 dxxdrho += dacdrho*Flambda*Fdelta*am*sin(phase) + ac*dFlambdadrho*Fdelta*am*sin(phase) + ac*Flambda*dFdeltadrho*am*sin(phase) + ac*Flambda*Fdelta*damdrho*sin(phase) + ac*Flambda*Fdelta*am*cos(phase)*dphasedrho; 3298 dxxdtheta += dacdtheta*Flambda*Fdelta*am*sin(phase) + ac*dFlambdadtheta*Fdelta*am*sin(phase) + ac*Flambda*dFdeltadtheta*am*sin(phase) + ac*Flambda*Fdelta*damdtheta*sin(phase) + ac*Flambda*Fdelta*am*cos(phase)*dphasedtheta; 3299 dxxdphi += dacdphi*Flambda*Fdelta*am*sin(phase) + ac*dFlambdadphi*Fdelta*am*sin(phase) + ac*Flambda*dFdeltadphi*am*sin(phase) + ac*Flambda*Fdelta*damdphi*sin(phase) + ac*Flambda*Fdelta*am*cos(phase)*dphasedphi; 3300 3301 } 3302 3303 /* convolution to avoid negative density values. No restriction on positive values, ht(x) = x */ 3304 3305 halftanh(xx,&ht,&dht,&d2ht); 3306 3307 nefsne += ht; 3308 dnefsnedrho += dht*dxxdrho; 3309 dnefsnedtheta += dht*dxxdtheta; 3310 dnefsnedphi += dht*dxxdphi; 3311 } 3312 3313 if (fluctparam.ne_model[imodel][0] == 6) {/* 2-D Gaussian model (rho,cm,cn), absolute epsi values (drift wave model, local phase approx. ) */ 3314 3315 /* Note that epsi_perp = fluctparam.ne_epsi_theta */ 3316 3317 ac = 2.0*sqrt(2.0*PI)*fluctparam.ne_sigmar_max[imodel][0]*sqrt(fluctparam.ne_epsi_rho[imodel][0]*fluctparam.ne_epsi_theta[imodel][0]/L_rho/xL_perp); 3318 dacdrho = -0.5*ac*(dL_rhodrho/L_rho + dxL_perpdrho/xL_perp); 3319 dacdtheta = -0.5*ac*(dL_rhodtheta/L_rho + dxL_perpdtheta/xL_perp); 3320 dacdphi = -0.5*ac*(dL_rhodphi/L_rho + dxL_perpdphi/xL_perp); 3321 3322 for (il = fluctparam.ne_lmin[imodel][0];il <= fluctparam.ne_lmax[imodel][0];il++) { 3323 for (im = fluctparam.ne_mmin[imodel][0];im <= fluctparam.ne_mmax[imodel][0];im++) { 3324 3325 iphase = (int)dl*(im-(int)fluctparam.ne_mmin[imodel][0]) + (il-(int)fluctparam.ne_lmin[imodel][0]) + 1; 3326 3327 kperp = 2*PI*im/xL_perp; 3328 dkperpdrho = -kperp/xL_perp*dxL_perpdrho;; 3329 dkperpdtheta = 0.0; 3330 dkperpdphi = 0.0; 3331 3332 phase = 2*PI*il*Y[0] + (icm + cn0*(Y[2] - Y0[2])/equilparam.Rp[0])*kperp + fluctparam.ne_phase[imodel][iphase-1]; 3333 dphasedrho = 2*PI*il + (idcmdrho + dcn0drho*(Y[2] - Y0[2])/equilparam.Rp[0])*kperp + (icm + cn0*(Y[2] - Y0[2])/equilparam.Rp[0])*dkperpdrho; 3334 dphasedtheta = cm*kperp + (icm + cn0*(Y[2] - Y0[2])/equilparam.Rp[0])*dkperpdtheta; 3335 dphasedphi = cn0*kperp + (icm + cn0*(Y[2] - Y0[2])/equilparam.Rp[0])*dkperpdphi; 3336 3337 u_l = PI*fluctparam.ne_epsi_rho[imodel][0]*il/L_rho; 3338 u_m = PI*fluctparam.ne_epsi_theta[imodel][0]*im/xL_perp; 3339 3340 du_ldrho = -u_l/L_rho*dL_rhodrho; 3341 du_mdrho = -u_m/xL_perp*dxL_perpdrho; 3342 3343 du_ldtheta = -u_l/L_rho*dL_rhodtheta; 3344 du_mdtheta = -u_m/xL_perp*dxL_perpdtheta; 3345 3346 du_ldphi = -u_l/L_rho*dL_rhodphi; 3347 du_mdphi = -u_m/xL_perp*dxL_perpdphi; 3348 3349 expu_l = exp(-u_l*u_l/2); 3350 expu_m = exp(-u_m*u_m/2); 3351 alm = expu_l*expu_m; 3352 3353 dexpu_ldrho = -expu_l*u_l*du_ldrho; 3354 dexpu_mdrho = -expu_m*u_m*du_mdrho; 3355 dalmdrho = dexpu_ldrho*expu_m + expu_l*dexpu_mdrho; 3356 3357 dexpu_ldtheta = -expu_l*u_l*du_ldtheta; 3358 dexpu_mdtheta = -expu_m*u_m*du_mdtheta; 3359 dalmdtheta = dexpu_ldtheta*expu_m + expu_l*dexpu_mdtheta; 3360 3361 dexpu_ldphi = -expu_l*u_l*du_ldphi; 3362 dexpu_mdphi = -expu_m*u_m*du_mdphi; 3363 dalmdphi = dexpu_ldphi*expu_m + expu_l*dexpu_mdphi; 3364 3365 xx += ac*Flambda*Fdelta*alm*sin(phase); 3366 dxxdrho += dacdrho*Flambda*Fdelta*alm*sin(phase) + ac*dFlambdadrho*Fdelta*alm*sin(phase) + ac*Flambda*dFdeltadrho*alm*sin(phase) + ac*Flambda*Fdelta*dalmdrho*sin(phase) + ac*Flambda*Fdelta*alm*cos(phase)*dphasedrho; 3367 dxxdtheta += dacdtheta*Flambda*Fdelta*alm*sin(phase) + ac*dFlambdadtheta*Fdelta*alm*sin(phase) + ac*Flambda*dFdeltadtheta*alm*sin(phase) + ac*Flambda*Fdelta*dalmdtheta*sin(phase) + ac*Flambda*Fdelta*alm*cos(phase)*dphasedtheta; 3368 dxxdphi += dacdphi*Flambda*Fdelta*alm*sin(phase) + ac*dFlambdadphi*Fdelta*alm*sin(phase) + ac*Flambda*dFdeltadphi*alm*sin(phase) + ac*Flambda*Fdelta*dalmdphi*sin(phase) + ac*Flambda*Fdelta*alm*cos(phase)*dphasedphi; 3369 3370 } 3371 } 3372 3373 /* convolution to avoid negative density values. No restriction on positive values, ht(x) = x */ 3374 3375 halftanh(xx,&ht,&dht,&d2ht); 3376 3377 nefsne += ht; 3378 dnefsnedrho += dht*dxxdrho; 3379 dnefsnedtheta += dht*dxxdtheta; 3380 dnefsnedphi += dht*dxxdphi; 3381 } 3382 } 3383 } 3384 3385 if (fluctparam.B_nmodel[0] > 0) {/* Magnetic field fluctuations or ripple */ 3386 3387 cta = cos(Y[1])*raymagnetic.calpha[0] + sin(Y[1])*raymagnetic.salpha[0]; 3388 sta = -cos(Y[1])*raymagnetic.salpha[0] + sin(Y[1])*raymagnetic.calpha[0]; 3389 3390 dctadrho = cos(Y[1])*raymagnetic.dcalphadY[0] + sin(Y[1])*raymagnetic.dsalphadY[0]; 3391 dctadtheta = cos(Y[1])*raymagnetic.dcalphadY[1] + sin(Y[1])*raymagnetic.dsalphadY[1] - sta; 3392 dctadphi = cos(Y[1])*raymagnetic.dcalphadY[2]*equilparam.Rp[0] + sin(Y[1])*raymagnetic.dsalphadY[2]*equilparam.Rp[0]; 3393 3394 dstadrho = - cos(Y[1])*raymagnetic.dsalphadY[0] + sin(Y[1])*raymagnetic.dcalphadY[0]; 3395 dstadtheta = - cos(Y[1])*raymagnetic.dsalphadY[1] + sin(Y[1])*raymagnetic.dcalphadY[1] + cta; 3396 dstadphi = - cos(Y[1])*raymagnetic.dsalphadY[2]*equilparam.Rp[0] + sin(Y[1])*raymagnetic.dcalphadY[2]*equilparam.Rp[0]; 3397 3398 for (imodel=0; imodel < fluctparam.B_nmodel[0]; imodel++) { 3399 3400 if (fluctparam.B_model[imodel][0] == 1) {/* Gaussian fluctuation spectrum */ 3401 3402 /* 3403 for (ikperp=0; ikperp < fluctparam.B_nkperp[imodel][0]; ikperp++) { 3404 3405 phaseB = gphase*fluctparam.B_kperp[imodel][ikperp] + fluctparam.B_phase[imodel][ikperp]; 3406 dphaseBdrho = dgphasedrho*fluctparam.B_kperp[imodel][ikperp]; 3407 dphaseBdtheta = dgphasedtheta*fluctparam.B_kperp[imodel][ikperp]; 3408 dphaseBdphi = dgphasedphi*fluctparam.B_kperp[imodel][ikperp]; 3409 3410 ff0 = sqrt(2*(fluctparam.B_kperp[imodel][1]-fluctparam.B_kperp[imodel][0])/sqrt(2*PI)); 3411 3412 ff1 = exp(-pow(fluctparam.B_kperp[imodel][ikperp]-krB[imodel],2)/pow(kcB[imodel],2)/4); 3413 dff1drho = ff1*(fluctparam.B_kperp[imodel][ikperp]-krB[imodel])*((fluctparam.B_kperp[imodel][ikperp]-krB[imodel])*dkcBdrho[imodel] + kcB[imodel]*dkrBdrho[imodel])/2/pow(kcB[imodel],3); 3414 dff1dtheta = ff1*(fluctparam.B_kperp[imodel][ikperp]-krB[imodel])*((fluctparam.B_kperp[imodel][ikperp]-krB[imodel])*dkcBdtheta[imodel] + kcB[imodel]*dkrBdtheta[imodel])/2/pow(kcB[imodel],3); 3415 3416 ff2 = 1./sqrt(kcB[imodel]); 3417 dff2drho = -dkcBdrho[imodel]/sqrt(kcB[imodel])/kcB[imodel]/2.0; 3418 dff2dtheta = -dkcBdtheta[imodel]/sqrt(kcB[imodel])/kcB[imodel]/2.0; 3419 3420 BxfsB = ff0*sfBx[imodel]*ff1*ff2*cos(phaseB); 3421 dBxfsBdrho = ff0*(dsfBxdrho[imodel]*cos(phaseB)*ff1*ff2 - sfBx[imodel]*sin(phaseB)*dphaseBdrho*ff1*ff2 + sfBx[imodel]*cos(phaseB)*dff1drho*ff2 + sfBx[imodel]*cos(phaseB)*ff1*dff2drho); 3422 dBxfsBdtheta = ff0*(dsfBxdtheta[imodel]*cos(phaseB)*ff1*ff2 - sfBx[imodel]*sin(phaseB)*dphaseBdtheta*ff1*ff2 + sfBx[imodel]*cos(phaseB)*dff1dtheta*ff2 + sfBx[imodel]*cos(phaseB)*ff1*dff2dtheta); 3423 dBxfsBdphi = - ff0*sfBx[imodel]*sin(phaseB)*dphaseBdphi*ff1*ff2; 3424 3425 ByfsB = ff0*sfBy[imodel]*ff1*ff2*cos(phaseB); 3426 dByfsBdrho = ff0*(dsfBydrho[imodel]*cos(phaseB)*ff1*ff2 - sfBy[imodel]*sin(phaseB)*dphaseBdrho*ff1*ff2 + sfBy[imodel]*cos(phaseB)*dff1drho*ff2 + sfBy[imodel]*cos(phaseB)*ff1*dff2drho); 3427 dByfsBdtheta = ff0*(dsfBydtheta[imodel]*cos(phaseB)*ff1*ff2 - sfBy[imodel]*sin(phaseB)*dphaseBdtheta*ff1*ff2 + sfBy[imodel]*cos(phaseB)*dff1dtheta*ff2 + sfBy[imodel]*cos(phaseB)*ff1*dff2dtheta); 3428 dByfsBdphi = - ff0*sfBy[imodel]*sin(phaseB)*dphaseBdphi*ff1*ff2; 3429 3430 BzfsB = ff0*sfBz[imodel]*ff1*ff2*cos(phaseB); 3431 dBzfsBdrho = ff0*(dsfBzdrho[imodel]*cos(phaseB)*ff1*ff2 - sfBz[imodel]*sin(phaseB)*dphaseBdrho*ff1*ff2 + sfBz[imodel]*cos(phaseB)*dff1drho*ff2 + sfBz[imodel]*cos(phaseB)*ff1*dff2drho); 3432 dBzfsBdtheta = ff0*(dsfBzdtheta[imodel]*cos(phaseB)*ff1*ff2 - sfBz[imodel]*sin(phaseB)*dphaseBdtheta*ff1*ff2 + sfBz[imodel]*cos(phaseB)*dff1dtheta*ff2 + sfBz[imodel]*cos(phaseB)*ff1*dff2dtheta); 3433 dBzfsBdphi = - ff0*sfBz[imodel]*sin(phaseB)*dphaseBdphi*ff1*ff2; 3434 */ 3435 3436 /* mexPrintf("Y[0],Y[1],Y[2],Bfx[0],dBxfdY[0],dBxfdY[1],dBxfdY[2]:%25.15g,%25.15g,%25.15g,%25.15g,%25.15g,%25.15g,%25.15g\n",Y[0],Y[1],Y[2],Bxf,dBxfdrho,dBxfdtheta,dBxfdphi);*/ 3437 /* mexPrintf("Y[0],Y[1],Y[2],Bfy[0],dByfdY[0],dByfdY[1],dByfdY[2]:%25.15g,%25.15g,%25.15g,%25.15g,%25.15g,%25.15g,%25.15g\n",Y[0],Y[1],Y[2],Byf,dByfdrho,dByfdtheta,dByfdphi);*/ 3438 /* mexPrintf("Y[0],Y[1],Y[2],Bfz[0],dBzfdY[0],dBzfdY[1],dBzfdY[2]:%25.15g,%25.15g,%25.15g,%25.15g,%25.15g,%25.15g,%25.15g\n",Y[0],Y[1],Y[2],Bzf,dBzfdrho,dBzfdtheta,dBzfdphi); 3439 3440 } 3441 */ 3442 } 3443 3444 if (fluctparam.B_model[imodel][0] == 0) {/* Magnetic ripple modulation */ 3445 3446 ppvald_2D(rayfluctuations.B_sfx_fit[imodel],rayparam.dS[0],Y[0],Y[1],&sfBx[imodel],&dsfBxdrho[imodel],&dsfBxdtheta[imodel],&d2sfBxdtheta2[imodel],&d2sfBxdthetadrho[imodel]); 3447 ppvald_2D(rayfluctuations.B_sfy_fit[imodel],rayparam.dS[0],Y[0],Y[1],&sfBy[imodel],&dsfBydrho[imodel],&dsfBydtheta[imodel],&d2sfBydtheta2[imodel],&d2sfBydthetadrho[imodel]); 3448 ppvald_2D(rayfluctuations.B_sfz_fit[imodel],rayparam.dS[0],Y[0],Y[1],&sfBz[imodel],&dsfBzdrho[imodel],&dsfBzdtheta[imodel],&d2sfBzdtheta2[imodel],&d2sfBzdthetadrho[imodel]); 3449 3450 phaseB = fluctparam.B_nmax[imodel][0]*Y[2]/equilparam.Rp[0]; 3451 dphaseBdrho = 0.0; 3452 dphaseBdtheta = 0.0; 3453 dphaseBdphi = fluctparam.B_nmax[imodel][0]; 3454 3455 BxfsB = sfBx[imodel]*sin(phaseB); 3456 dBxfsBdrho = dsfBxdrho[imodel]*sin(phaseB); 3457 dBxfsBdtheta = dsfBxdtheta[imodel]*sin(phaseB); 3458 dBxfsBdphi = sfBx[imodel]*cos(phaseB)*dphaseBdphi; 3459 3460 ByfsB = sfBy[imodel]*sin(phaseB); 3461 dByfsBdrho = dsfBydrho[imodel]*sin(phaseB); 3462 dByfsBdtheta = dsfBydtheta[imodel]*sin(phaseB); 3463 dByfsBdphi = sfBy[imodel]*cos(phaseB)*dphaseBdphi; 3464 3465 BzfsB = sfBz[imodel]*cos(phaseB); 3466 dBzfsBdrho = dsfBzdrho[imodel]*cos(phaseB); 3467 dBzfsBdtheta = dsfBzdtheta[imodel]*cos(phaseB); 3468 dBzfsBdphi = -sfBz[imodel]*sin(phaseB)*dphaseBdphi; 3469 3470 /* add ripple effect on densities and temperatures (electron and ion) */ 3471 3472 Brho0 = raymagnetic.B[0]*(cta*sfBx[imodel] + sta*sfBy[imodel]); 3473 dBrho0drho = raymagnetic.dBdY[0]*(cta*sfBx[imodel] + sta*sfBy[imodel]) + raymagnetic.B[0]*(dctadrho*sfBx[imodel] + cta*dsfBxdrho[imodel] + dstadrho*sfBy[imodel] + sta*dsfBydrho[imodel]); 3474 dBrho0dtheta = raymagnetic.dBdY[1]*(cta*sfBx[imodel] + sta*sfBy[imodel]) + raymagnetic.B[0]*(dctadtheta*sfBx[imodel] + cta*dsfBxdtheta[imodel] + dstadtheta*sfBy[imodel] + sta*dsfBydtheta[imodel]); 3475 3476 lambda = Brho0*raymagnetic.gradrhon[0]*equilparam.Rp[0]/Bz/fluctparam.B_nmax[imodel][0]/equilparam.ap[0]; 3477 dlambdadrho = (dBrho0drho*raymagnetic.gradrhon[0] + Brho0*raymagnetic.dgradrhondY[0] - Brho0*raymagnetic.gradrhon[0]*dBzdrho/Bz)*equilparam.Rp[0]/Bz/fluctparam.B_nmax[imodel][0]/equilparam.ap[0]; 3478 dlambdadtheta = (dBrho0dtheta*raymagnetic.gradrhon[0] + Brho0*raymagnetic.dgradrhondY[1] - Brho0*raymagnetic.gradrhon[0]*dBzdtheta/Bz)*equilparam.Rp[0]/Bz/fluctparam.B_nmax[imodel][0]/equilparam.ap[0]; 3479 3480 rhorip = Y[0] + lambda*cos(phaseB); 3481 drhodrhorip = 1.0 + dlambdadrho*cos(phaseB); 3482 drhodthetarip = dlambdadtheta*cos(phaseB); 3483 drhodphirip = - dphaseBdphi*lambda*sin(phaseB); 3484 3485 /* Electron density */ 3486 3487 ppvald_1D(rayequil.ne_fit,rayparam.dS[0],1.0,&val,&dvaldrho,&d2valdrho2); /*value at the separatrix */ 3488 ne_sep = val; 3489 dnedrho_sep = dvaldrho; 3490 3491 if (dnedrho_sep == 0) { 3492 rho_neeq0 = 1.0e20; 3493 } else { 3494 rho_neeq0 = - ne_sep/dnedrho_sep + 1.0; 3495 } 3496 3497 if (rhorip <= 1.0) { 3498 ppvald_1D(rayequil.ne_fit,rayparam.dS[0],rhorip,&val,&dvaldrho,&d2valdrho2); 3499 nerip = val; 3500 dnedrhorip = dvaldrho*drhodrhorip; 3501 dnedthetarip = dvaldrho*drhodthetarip; 3502 dnedphirip = dvaldrho*drhodphirip; 3503 } 3504 3505 if ((rhorip > 1.0) & (rhorip <= rho_neeq0)) { 3506 nerip = ne_sep + dnedrho_sep*(rhorip - 1.0); /* SOL */ 3507 dnedrhorip = dnedrho_sep*drhodrhorip; 3508 dnedthetarip = dnedrho_sep*drhodthetarip; 3509 dnedphirip = dnedrho_sep*drhodphirip; 3510 } 3511 3512 if (rhorip > rho_neeq0) { 3513 nerip = 0.0; /*vacuum */ 3514 dnedrhorip = 0.0; 3515 dnedthetarip = 0.0; 3516 dnedphirip = 0.0; 3517 } 3518 3519 ne_tilde = nerip - rayprofiles.ne[0]; 3520 dnedrho_tilde = dnedrhorip - rayprofiles.dnedY[0]; 3521 dnedtheta_tilde = dnedthetarip; 3522 dnedphi_tilde = dnedphirip; 3523 3524 ner_tilde = ne_tilde/rayprofiles.ne[0]; 3525 dnerdrho_tilde = dnedrho_tilde/rayprofiles.ne[0] - ne_tilde*rayprofiles.dnedY[0]/rayprofiles.ne[0]/rayprofiles.ne[0]; 3526 dnerdtheta_tilde = dnedtheta_tilde/rayprofiles.ne[0]; 3527 dnerdphi_tilde = dnedphi_tilde/rayprofiles.ne[0]; 3528 3529 /* mexPrintf("rho,theta,phi,rhorip,rho_neeq0,ne,dnedrho,nerip,dnedrhorip,dnedthetarip,dnedphirip,ner_tilde,dnerdrho_tilde,dnerdtheta_tilde,dnerdphi_tilde:%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g\n",Y[0],Y[1],Y[2],rhorip,rho_neeq0,rayprofiles.ne[0],rayprofiles.dnedY[0],nerip,dnedrhorip,dnedthetarip,dnedphirip,ner_tilde,dnerdrho_tilde,dnerdtheta_tilde,dnerdphi_tilde); 3530 mexPrintf("Brho0,raymagnetic.gradrhon[0],equilparam.Rp[0],BPHI,fluctparam.B_kperp[imodel][ikperp],lambda:%g,%g,%g,%g,%g,%g\n",Brho0,raymagnetic.gradrhon[0],equilparam.Rp[0],BPHI,fluctparam.B_kperp[imodel][ikperp],lambda); 3531 */ 3532 nefsne += ner_tilde;/* add the relative contribution of magnetic ripple to the density perturbation */ 3533 dnefsnedrho += dnerdrho_tilde; 3534 dnefsnedtheta += dnerdtheta_tilde; 3535 dnefsnedphi += dnerdphi_tilde; 3536 3537 /* Electron temperature */ 3538 3539 ppvald_1D(rayequil.Te_fit,rayparam.dS[0],1.0,&val,&dvaldrho,&d2valdrho2); /*value at the separatrix */ 3540 Te_sep = val; 3541 dTedrho_sep = dvaldrho; 3542 3543 if (dTedrho_sep == 0) { 3544 rho_Teeq0 = 1.0e20; 3545 } else { 3546 rho_Teeq0 = - Te_sep/dTedrho_sep + 1.0; 3547 } 3548 3549 if (rhorip <= 1.0) { 3550 ppvald_1D(rayequil.Te_fit,rayparam.dS[0],rhorip,&val,&dvaldrho,&d2valdrho2); 3551 Terip = val; 3552 dTedrhorip = dvaldrho*drhodrhorip; 3553 dTedthetarip = dvaldrho*drhodthetarip; 3554 dTedphirip = dvaldrho*drhodphirip; 3555 } 3556 3557 if ((rhorip > 1.0) & (rhorip <= rho_Teeq0)) { 3558 Terip = Te_sep + dTedrho_sep*(rhorip - 1.0); /* SOL */ 3559 dTedrhorip = dTedrho_sep*drhodrhorip; 3560 dTedthetarip = dTedrho_sep*drhodthetarip; 3561 dTedphirip = dTedrho_sep*drhodphirip; 3562 } 3563 3564 if (rhorip > rho_Teeq0) { 3565 Terip = 0.0; /*vacuum */ 3566 dTedrhorip = 0.0; 3567 dTedthetarip = 0.0; 3568 dTedphirip = 0.0; 3569 } 3570 3571 Te_tilde = Terip - rayprofiles.Te[0]; 3572 dTedrho_tilde = dTedrhorip - rayprofiles.dTedY[0]; 3573 dTedtheta_tilde = dTedthetarip; 3574 dTedphi_tilde = dTedphirip; 3575 3576 Ter_tilde = Te_tilde/rayprofiles.Te[0]; 3577 dTerdrho_tilde = dTedrho_tilde/rayprofiles.Te[0] - Te_tilde*rayprofiles.dTedY[0]/rayprofiles.Te[0]/rayprofiles.Te[0]; 3578 dTerdtheta_tilde = dTedtheta_tilde/rayprofiles.Te[0]; 3579 dTerdphi_tilde = dTedphi_tilde/rayprofiles.Te[0]; 3580 3581 TefsTe += Ter_tilde;/* add the relative contribution of magnetic ripple to the electron temperature perturbation */ 3582 dTefsTedrho += dTerdrho_tilde; 3583 dTefsTedtheta += dTerdtheta_tilde; 3584 dTefsTedphi += dTerdphi_tilde; 3585 3586 /* ion densities */ 3587 3588 for (is=0;is /*value at the separatrix */ 3591 zni_sep[is] = zval[is]; 3592 dznidrho_sep[is] = dzvaldrho[is]; 3593 3594 if (dznidrho_sep[is] == 0) { 3595 rho_znieq0[is] = 1.0e20; 3596 } else { 3597 rho_znieq0[is] = - zni_sep[is]/dznidrho_sep[is] + 1.0; 3598 } 3599 3600 if (rhorip <= 1.0) { 3601 ppvald_1D(rayequil.zni_fit,rayparam.dS[0],rhorip,zval,dzvaldrho,d2zvaldrho2); 3602 znirip[is] = zval[is]; 3603 dznidrhorip[is] = dzvaldrho[is]*drhodrhorip; 3604 dznidthetarip[is] = dzvaldrho[is]*drhodthetarip; 3605 dznidphirip[is] = dzvaldrho[is]*drhodphirip; 3606 } 3607 3608 if ((rhorip > 1.0) & (rhorip <= rho_znieq0[is])) { 3609 znirip[is] = zni_sep[is] + dznidrho_sep[is]*(rhorip - 1.0); /* SOL */ 3610 dznidrhorip[is] = dznidrho_sep[is]*drhodrhorip; 3611 dznidthetarip[is] = dznidrho_sep[is]*drhodthetarip; 3612 dznidphirip[is] = dznidrho_sep[is]*drhodphirip; 3613 } 3614 3615 if (rhorip > rho_znieq0[is]) { 3616 znirip[is] = 0.0; /*vacuum */ 3617 dznidrhorip[is] = 0.0; 3618 dznidthetarip[is] = 0.0; 3619 dznidphirip[is] = 0.0; 3620 } 3621 3622 zni_tilde[is] = znirip[is] - rayprofiles.zni[is]; 3623 dznidrho_tilde[is] = dznidrhorip[is] - rayprofiles.dznidY[is][0]; 3624 dznidtheta_tilde[is] = dznidthetarip[is]; 3625 dznidphi_tilde[is] = dznidphirip[is]; 3626 3627 /*mexPrintf("is,ns,rayprofiles.zni[is],%d,%d,%g\n",is,equilparam.ns[0],rayprofiles.zni[is]);*/ 3628 3629 if (rayprofiles.zni[is] > 0.0) { 3630 3631 /* mexPrintf("is valide,%d\n",is);*/ 3632 3633 znir_tilde[is] = zni_tilde[is]/rayprofiles.zni[is]; 3634 dznirdrho_tilde[is] = dznidrho_tilde[is]/rayprofiles.zni[is] - zni_tilde[is]*rayprofiles.dznidY[is][0]/rayprofiles.zni[is]/rayprofiles.zni[is]; 3635 dznirdtheta_tilde[is] = dznidtheta_tilde[is]/rayprofiles.zni[is]; 3636 dznirdphi_tilde[is] = dznidphi_tilde[is]/rayprofiles.zni[is]; 3637 3638 znifszni[is] += znir_tilde[is];/* add the relative contribution of magnetic ripple to the ion densities perturbations */ 3639 dznifsznidrho[is] += dznirdrho_tilde[is]; 3640 dznifsznidtheta[is] += dznirdtheta_tilde[is]; 3641 dznifsznidphi[is] += dznirdphi_tilde[is]; 3642 } 3643 3644 /* ion temperatures */ 3645 3646 ppvald_1D(rayequil.zTi_fit,rayparam.dS[0],1.0,zval,dzvaldrho,d2zvaldrho2); /*value at the separatrix */ 3647 zTi_sep[is] = zval[is]; 3648 dzTidrho_sep[is] = dzvaldrho[is]; 3649 3650 if (dzTidrho_sep[is] == 0) { 3651 rho_zTieq0[is] = 1.0e20; 3652 } else { 3653 rho_zTieq0[is] = - zTi_sep[is]/dzTidrho_sep[is] + 1.0; 3654 } 3655 3656 if (rhorip <= 1.0) { 3657 ppvald_1D(rayequil.zTi_fit,rayparam.dS[0],rhorip,zval,dzvaldrho,d2zvaldrho2); 3658 zTirip[is] = zval[is]; 3659 dzTidrhorip[is] = dzvaldrho[is]*drhodrhorip; 3660 dzTidthetarip[is] = dzvaldrho[is]*drhodthetarip; 3661 dzTidphirip[is] = dzvaldrho[is]*drhodphirip; 3662 } 3663 3664 if ((rhorip > 1.0) & (rhorip <= rho_zTieq0[is])) { 3665 zTirip[is] = zTi_sep[is] + dzTidrho_sep[is]*(rhorip - 1.0); /* SOL */ 3666 dzTidrhorip[is] = dzTidrho_sep[is]*drhodrhorip; 3667 dzTidthetarip[is] = dzTidrho_sep[is]*drhodthetarip; 3668 dzTidphirip[is] = dzTidrho_sep[is]*drhodphirip; 3669 } 3670 3671 if (rhorip > rho_zTieq0[is]) { 3672 zTirip[is] = 0.0; /*vacuum */ 3673 dzTidrhorip[is] = 0.0; 3674 dzTidthetarip[is] = 0.0; 3675 dzTidphirip[is] = 0.0; 3676 } 3677 3678 zTi_tilde[is] = zTirip[is] - rayprofiles.zTi[is]; 3679 dzTidrho_tilde[is] = dzTidrhorip[is] - rayprofiles.dzTidY[is][0]; 3680 dzTidtheta_tilde[is] = dzTidthetarip[is]; 3681 dzTidphi_tilde[is] = dzTidphirip[is]; 3682 3683 zTir_tilde[is] = zTi_tilde[is]/rayprofiles.zTi[is]; 3684 dzTirdrho_tilde[is] = dzTidrho_tilde[is]/rayprofiles.zTi[is] - zTi_tilde[is]*rayprofiles.dzTidY[is][0]/rayprofiles.zTi[is]/rayprofiles.zTi[is]; 3685 dzTirdtheta_tilde[is] = dzTidtheta_tilde[is]/rayprofiles.zTi[is]; 3686 dzTirdphi_tilde[is] = dzTidphi_tilde[is]/rayprofiles.zTi[is]; 3687 3688 zTifszTi[is] += zTir_tilde[is];/* add the relative contribution of magnetic ripple to the ion temperatures perturbations */ 3689 dzTifszTidrho[is] += dzTirdrho_tilde[is]; 3690 dzTifszTidtheta[is] += dzTirdtheta_tilde[is]; 3691 dzTifszTidphi[is] += dzTirdphi_tilde[is]; 3692 } 3693 3694 } 3695 3696 BrhofsB += cta*BxfsB + sta*ByfsB; 3697 dBrhofsBdrho += dctadrho*BxfsB + cta*dBxfsBdrho + dstadrho*ByfsB + sta*dByfsBdrho; 3698 dBrhofsBdtheta += dctadtheta*BxfsB + cta*dBxfsBdtheta + dstadtheta*ByfsB + sta*dByfsBdtheta; 3699 dBrhofsBdphi += dctadphi*BxfsB + cta*dBxfsBdphi + dstadphi*ByfsB + sta*dByfsBdphi; 3700 3701 BsfsB += cta*ByfsB - sta*BxfsB; 3702 dBsfsBdrho += dctadrho*ByfsB + cta*dByfsBdrho - dstadrho*BxfsB - sta*dBxfsBdrho; 3703 dBsfsBdtheta += dctadtheta*ByfsB + cta*dByfsBdtheta - dstadtheta*BxfsB - sta*dBxfsBdtheta; 3704 dBsfsBdphi += dctadphi*ByfsB + cta*dByfsBdphi - dstadphi*BxfsB - sta*dBxfsBdphi; 3705 3706 BphifsB += BzfsB; 3707 dBphifsBdrho += dBzfsBdrho; 3708 dBphifsBdtheta += dBzfsBdtheta; 3709 dBphifsBdphi += dBzfsBdphi; 3710 3711 } 3712 } 3713 3714 /* Calculation of the perturbed magnetic field and its derivatives */ 3715 3716 Brho = (raymagnetic.Brhon[0] + BrhofsB)*raymagnetic.B[0]; 3717 Bs = (raymagnetic.Bsn[0] + BsfsB)*raymagnetic.B[0]; 3718 Bphi = (raymagnetic.Bzn[0] + BphifsB)*raymagnetic.B[0]; 3719 B = sqrt(Brho*Brho + Bs*Bs + Bphi*Bphi); 3720 3721 Brhon = Brho/B;/* Normalization to the new local value of B */ 3722 Bsn = Bs/B; 3723 Bphin = Bphi/B; 3724 3725 dBrhodrho = (raymagnetic.dBrhondY[0] + dBrhofsBdrho)*raymagnetic.B[0] + (raymagnetic.Brhon[0] + BrhofsB)*raymagnetic.dBdY[0]; 3726 dBrhodtheta = (raymagnetic.dBrhondY[1] + dBrhofsBdtheta)*raymagnetic.B[0] + (raymagnetic.Brhon[0] + BrhofsB)*raymagnetic.dBdY[1]; 3727 dBrhodphi = (raymagnetic.dBrhondY[2]*equilparam.Rp[0] + dBrhofsBdphi)*raymagnetic.B[0] + (raymagnetic.Brhon[0] + BrhofsB)*raymagnetic.dBdY[2]*equilparam.Rp[0]; 3728 3729 dBsdrho = (raymagnetic.dBsndY[0] + dBsfsBdrho)*raymagnetic.B[0] + (raymagnetic.Bsn[0] + BsfsB)*raymagnetic.dBdY[0]; 3730 dBsdtheta = (raymagnetic.dBsndY[1] + dBsfsBdtheta)*raymagnetic.B[0] + (raymagnetic.Bsn[0] + BsfsB)*raymagnetic.dBdY[1]; 3731 dBsdphi = (raymagnetic.dBsndY[2]*equilparam.Rp[0] + dBsfsBdphi)*raymagnetic.B[0] + (raymagnetic.Bsn[0] + BsfsB)*raymagnetic.dBdY[2]*equilparam.Rp[0]; 3732 3733 dBphidrho = (raymagnetic.dBzndY[0] + dBphifsBdrho)*raymagnetic.B[0] + (raymagnetic.Bzn[0] + BphifsB)*raymagnetic.dBdY[0]; 3734 dBphidtheta = (raymagnetic.dBzndY[1] + dBphifsBdtheta)*raymagnetic.B[0] + (raymagnetic.Bzn[0] + BphifsB)*raymagnetic.dBdY[1]; 3735 dBphidphi = (raymagnetic.dBzndY[2]*equilparam.Rp[0] + dBphifsBdphi)*raymagnetic.B[0] + (raymagnetic.Bzn[0] + BphifsB)*raymagnetic.dBdY[2]*equilparam.Rp[0]; 3736 3737 dBdrho = Brhon*dBrhodrho + Bsn*dBsdrho + Bphin*dBphidrho; 3738 dBdtheta = Brhon*dBrhodtheta + Bsn*dBsdtheta + Bphin*dBphidtheta; 3739 dBdphi = Brhon*dBrhodphi + Bsn*dBsdphi + Bphin*dBphidphi; 3740 3741 raymagnetic.Brhon[0] = Brhon; 3742 raymagnetic.dBrhondY[0] = (dBrhodrho - Brhon*dBdrho)/B; 3743 raymagnetic.dBrhondY[1] = (dBrhodtheta - Brhon*dBdtheta)/B; 3744 raymagnetic.dBrhondY[2] = (dBrhodphi - Brhon*dBdphi)/B/equilparam.Rp[0]; 3745 3746 raymagnetic.Bsn[0] = Bsn; 3747 raymagnetic.dBsndY[0] = (dBsdrho - Bsn*dBdrho)/B; 3748 raymagnetic.dBsndY[1] = (dBsdtheta - Bsn*dBdtheta)/B; 3749 raymagnetic.dBsndY[2] = (dBsdphi - Bsn*dBdphi)/B/equilparam.Rp[0]; 3750 3751 raymagnetic.Bzn[0] = Bphin; 3752 raymagnetic.dBzndY[0] = (dBphidrho - Bphin*dBdrho)/B; 3753 raymagnetic.dBzndY[1] = (dBphidtheta - Bphin*dBdtheta)/B; 3754 raymagnetic.dBzndY[2] = (dBphidphi - Bphin*dBdphi)/B/equilparam.Rp[0]; 3755 3756 raymagnetic.B[0] = B; 3757 raymagnetic.dBdY[0] = dBdrho; 3758 raymagnetic.dBdY[1] = dBdtheta; 3759 raymagnetic.dBdY[2] = dBdphi/equilparam.Rp[0]; 3760 3761 raymagnetic.rhorip[0] = rhorip; 3762 raymagnetic.drhoripdY[0] = drhodrhorip; 3763 raymagnetic.drhoripdY[1] = drhodthetarip; 3764 raymagnetic.drhoripdY[2] = drhodphirip/equilparam.Rp[0]; 3765 3766 /* Calculation of the perturbed electron density and its derivatives */ 3767 3768 /* mexPrintf("rho,theta,phi,ner[0],dnerdY[0],dnerdY[1],dnerdY[2]:%25.15g,%25.15g,%25.15g,%25.15g,%25.15g,%25.15g,%25.15g\n",Y[0],Y[1],Y[2],nefsne,dnefsnedrho,dnefsnedtheta,dnefsnedphi);*/ 3769 3770 rayprofiles.dnedY[0] = rayprofiles.dnedY[0]*(1.0 + nefsne) + rayprofiles.ne[0]*dnefsnedrho; 3771 rayprofiles.dnedY[1] = rayprofiles.dnedY[1]*(1.0 + nefsne) + rayprofiles.ne[0]*dnefsnedtheta; 3772 rayprofiles.dnedY[2] = rayprofiles.dnedY[2]*(1.0 + nefsne) + rayprofiles.ne[0]*dnefsnedphi/equilparam.Rp[0]; 3773 rayprofiles.ne[0] = rayprofiles.ne[0]*(1.0 + nefsne); 3774 3775 /* Calculation of the perturbed electron temperature and it's derivatives */ 3776 3777 rayprofiles.dTedY[0] = rayprofiles.dTedY[0]*(1.0 + TefsTe) + rayprofiles.Te[0]*dTefsTedrho; 3778 rayprofiles.dTedY[1] = rayprofiles.dTedY[1]*(1.0 + TefsTe) + rayprofiles.Te[0]*dTefsTedtheta; 3779 rayprofiles.dTedY[2] = rayprofiles.dTedY[2]*(1.0 + TefsTe) + rayprofiles.Te[0]*dTefsTedphi/equilparam.Rp[0]; 3780 rayprofiles.Te[0] = rayprofiles.Te[0]*(1.0 + TefsTe); 3781 3782 for (is=0;is /* Calculation of the perturbed ion densities and their derivatives */ 3785 3786 rayprofiles.dznidY[is][0] = rayprofiles.dznidY[is][0]*(1.0 + znifszni[is]) + rayprofiles.zni[is]*dznifsznidrho[is]; 3787 rayprofiles.dznidY[is][1] = rayprofiles.dznidY[is][1]*(1.0 + znifszni[is]) + rayprofiles.zni[is]*dznifsznidtheta[is]; 3788 rayprofiles.dznidY[is][2] = rayprofiles.dznidY[is][2]*(1.0 + znifszni[is]) + rayprofiles.zni[is]*dznifsznidphi[is]/equilparam.Rp[0]; 3789 rayprofiles.zni[is] = rayprofiles.zni[is]*(1.0 + znifszni[is]); 3790 3791 /* Calculation of the perturbed ion temperatures and their derivatives */ 3792 3793 rayprofiles.dzTidY[is][0] = rayprofiles.dzTidY[is][0]*(1.0 + zTifszTi[is]) + rayprofiles.zTi[is]*dzTifszTidrho[is]; 3794 rayprofiles.dzTidY[is][1] = rayprofiles.dzTidY[is][1]*(1.0 + zTifszTi[is]) + rayprofiles.zTi[is]*dzTifszTidtheta[is]; 3795 rayprofiles.dzTidY[is][2] = rayprofiles.dzTidY[is][2]*(1.0 + zTifszTi[is]) + rayprofiles.zTi[is]*dzTifszTidphi[is]/equilparam.Rp[0]; 3796 rayprofiles.zTi[is] = rayprofiles.zTi[is]*(1.0 + zTifszTi[is]); 3797 3798 } 3799 3800 if(flag_metric == 2)/*Reset the equilibrium to the cartesian metric*/ 3801 { 3802 Y[0] = xbis; 3803 Y[1] = ybis; 3804 3805 save = raymagnetic.drndY[0]; 3806 raymagnetic.drndY[0] = drhodx*raymagnetic.drndY[0] + dthetadx*raymagnetic.drndY[1]; 3807 raymagnetic.drndY[1] = drhody*save + dthetady*raymagnetic.drndY[1]; 3808 3809 save = raymagnetic.dxndY[0]; 3810 raymagnetic.dxndY[0] = drhodx*raymagnetic.dxndY[0] + dthetadx*raymagnetic.dxndY[1]; 3811 raymagnetic.dxndY[1] = drhody*save + dthetady*raymagnetic.dxndY[1]; 3812 3813 save = raymagnetic.dyndY[0]; 3814 raymagnetic.dyndY[0] = drhodx*raymagnetic.dyndY[0] + dthetadx*raymagnetic.dyndY[1]; 3815 raymagnetic.dyndY[1] = drhody*save + dthetady*raymagnetic.dyndY[1]; 3816 3817 save = raymagnetic.dBrhondY[0]; 3818 raymagnetic.dBrhondY[0] = drhodx*raymagnetic.dBrhondY[0] + dthetadx*raymagnetic.dBrhondY[1]; 3819 raymagnetic.dBrhondY[1] = drhody*save + dthetady*raymagnetic.dBrhondY[1]; 3820 3821 save = raymagnetic.dBsndY[0]; 3822 raymagnetic.dBsndY[0] = drhodx*raymagnetic.dBsndY[0] + dthetadx*raymagnetic.dBsndY[1]; 3823 raymagnetic.dBsndY[1] = drhody*save + dthetady*raymagnetic.dBsndY[1]; 3824 3825 save = raymagnetic.dBzndY[0]; 3826 raymagnetic.dBzndY[0] = drhodx*raymagnetic.dBzndY[0] + dthetadx*raymagnetic.dBzndY[1]; 3827 raymagnetic.dBzndY[1] = drhody*save + dthetady*raymagnetic.dBzndY[1]; 3828 3829 save = raymagnetic.dBdY[0]; 3830 raymagnetic.dBdY[0] = drhodx*raymagnetic.dBdY[0] + dthetadx*raymagnetic.dBdY[1]; 3831 raymagnetic.dBdY[1] = drhody*save + dthetady*raymagnetic.dBdY[1]; 3832 3833 save = raymagnetic.dsalphadY[0]; 3834 raymagnetic.dsalphadY[0] = drhodx*raymagnetic.dsalphadY[0] + dthetadx*raymagnetic.dsalphadY[1]; 3835 raymagnetic.dsalphadY[1] = drhody*save + dthetady*raymagnetic.dsalphadY[1]; 3836 3837 save = raymagnetic.dcalphadY[0]; 3838 raymagnetic.dcalphadY[0] = drhodx*raymagnetic.dcalphadY[0] + dthetadx*raymagnetic.dcalphadY[1]; 3839 raymagnetic.dcalphadY[1] = drhody*save + dthetady*raymagnetic.dcalphadY[1]; 3840 3841 save = raymagnetic.dgradrhondY[0]; 3842 raymagnetic.dgradrhondY[0] = drhodx*raymagnetic.dgradrhondY[0] + dthetadx*raymagnetic.dgradrhondY[1]; 3843 raymagnetic.dgradrhondY[1] = drhody*save + dthetady*raymagnetic.dgradrhondY[1]; 3844 3845 save = raymagnetic.drhoripdY[0]; 3846 raymagnetic.drhoripdY[0] = drhodx*raymagnetic.drhoripdY[0] + dthetadx*raymagnetic.drhoripdY[1]; 3847 raymagnetic.drhoripdY[1] = drhody*save + dthetady*raymagnetic.drhoripdY[1]; 3848 3849 save = raymagnetic.dUpsilonndY[0]; 3850 raymagnetic.dUpsilonndY[0] = drhodx*raymagnetic.dUpsilonndY[0] + dthetadx*raymagnetic.dUpsilonndY[1]; 3851 raymagnetic.dUpsilonndY[1] = drhody*save + dthetady*raymagnetic.dUpsilonndY[1]; 3852 3853 save = rayprofiles.dTedY[0]; 3854 rayprofiles.dTedY[0] = drhodx*rayprofiles.dTedY[0] + dthetadx*rayprofiles.dTedY[1]; 3855 rayprofiles.dTedY[1] = drhody*save + dthetady*rayprofiles.dTedY[1]; 3856 3857 save = rayprofiles.dnedY[0]; 3858 rayprofiles.dnedY[0] = drhodx*rayprofiles.dnedY[0] + dthetadx*rayprofiles.dnedY[1]; 3859 rayprofiles.dnedY[1] = drhody*save + dthetady*rayprofiles.dnedY[1]; 3860 3861 for(is=0;is void build_raymagnetic(theta,raymagnetic,equilparam,x,dxdrho,dxdtheta,d2xdtheta2,d2xdthetadrho,d2xdrho2, 3877 y,dydrho,dydtheta,d2ydtheta2,d2ydthetadrho,d2ydrho2, 3878 r,drdrho,drdtheta,d2rdtheta2,d2rdthetadrho,d2rdrho2, 3879 calpha,dcalphadrho,dcalphadtheta,d2calphadtheta2,d2calphadthetadrho,d2calphadrho2, 3880 salpha,dsalphadrho,dsalphadtheta,d2salphadtheta2,d2salphadthetadrho,d2salphadrho2, 3881 gradrho,dgradrhodrho,dgradrhodtheta,d2gradrhodtheta2,d2gradrhodthetadrho,d2gradrhodrho2, 3882 Bx,dBxdrho,dBxdtheta,d2Bxdtheta2,d2Bxdthetadrho,d2Bxdrho2,dBxdz, 3883 By,dBydrho,dBydtheta,d2Bydtheta2,d2Bydthetadrho,d2Bydrho2,dBydz, 3884 Bz,dBzdrho,dBzdtheta,d2Bzdtheta2,d2Bzdthetadrho,d2Bzdrho2,dBzdz, 3885 BP,dBPdrho,dBPdtheta,d2BPdtheta2,d2BPdthetadrho,d2BPdrho2,dBPdz, 3886 B,dBdrho,dBdtheta,d2Bdtheta2,d2Bdthetadrho,d2Bdrho2,dBdz,flag_metric)/*Has to be modified under a change of metric*/ 3887 raymagnetic_format raymagnetic; 3888 equilparam_format equilparam; 3889 double theta; 3890 double x,dxdrho,dxdtheta,d2xdtheta2,d2xdthetadrho,d2xdrho2; 3891 double y,dydrho,dydtheta,d2ydtheta2,d2ydthetadrho,d2ydrho2; 3892 double r,drdrho,drdtheta,d2rdtheta2,d2rdthetadrho,d2rdrho2; 3893 double calpha,dcalphadrho,dcalphadtheta,d2calphadtheta2,d2calphadthetadrho,d2calphadrho2; 3894 double salpha,dsalphadrho,dsalphadtheta,d2salphadtheta2,d2salphadthetadrho,d2salphadrho2; 3895 double gradrho,dgradrhodrho,dgradrhodtheta,d2gradrhodtheta2,d2gradrhodthetadrho,d2gradrhodrho2; 3896 double Bx,dBxdrho,dBxdtheta,d2Bxdtheta2,d2Bxdthetadrho,d2Bxdrho2,dBxdz; 3897 double By,dBydrho,dBydtheta,d2Bydtheta2,d2Bydthetadrho,d2Bydrho2,dBydz; 3898 double Bz,dBzdrho,dBzdtheta,d2Bzdtheta2,d2Bzdthetadrho,d2Bzdrho2,dBzdz; 3899 double BP,dBPdrho,dBPdtheta,d2BPdtheta2,d2BPdthetadrho,d2BPdrho2,dBPdz; 3900 double B,dBdrho,dBdtheta,d2Bdtheta2,d2Bdthetadrho,d2Bdrho2,dBdz; 3901 int flag_metric; 3902 { 3903 double Upsilon,dUpsilondrho,dUpsilondtheta,d2Upsilondtheta2,d2Upsilondthetadrho,d2Upsilondrho2; 3904 3905 3906 /* WARNING: the definitions used in the DKE code, and here crucial for HXR calculations are the following 3907 1) the toroidal frame (R,Z,phi) is direct (phi is positive clockwise when the tokamak is seen from the top) 3908 2) the poloidal frame (r,theta,phi) is direct 3909 3) (psi,s,phi) must be direct : if Ip.phi > 0, then B.theta > 0 and psi > 0, and s.theta > 0 (s as the same direction of theta) 3910 4) the sign of psi is the sign of Ip.phi 3911 With the definitions above, if Ip is positive, psi is turned outward, Btheta is counterclockwise poloidally, and s too. The Ampere theorem is OK ! 3912 This definition is used also for DKE and HXR calculations 3913 */ 3914 3915 3916 if (isinf(equilparam.Rp[0]) == 1) {/* Toroidal factor. If Upsilon=1, cylindrical magnetic configuration */ 3917 Upsilon = 1.0; 3918 dUpsilondrho = 0.0; 3919 dUpsilondtheta = 0.0; 3920 } else { 3921 Upsilon = 1.0 + x/equilparam.Rp[0]; 3922 dUpsilondrho = dxdrho/equilparam.Rp[0]; 3923 dUpsilondtheta = dxdtheta/equilparam.Rp[0]; 3924 } 3925 if (flag_metric == 1)/*Curvilinear case*/ 3926 { 3927 raymagnetic.Brhon[0] = 0.0;/* Normalized radial magnetic field */ 3928 raymagnetic.dBrhondY[0] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3929 raymagnetic.dBrhondY[1] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3930 raymagnetic.dBrhondY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3931 3932 raymagnetic.Bsn[0] = BP/B;/* Normalized poloidal magnetic field */ 3933 raymagnetic.dBsndY[0] = (dBPdrho/B - BP*dBdrho/B/B); 3934 raymagnetic.dBsndY[1] = (dBPdtheta/B - BP*dBdtheta/B/B); 3935 raymagnetic.dBsndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3936 3937 raymagnetic.Bzn[0] = Bz/B;/* Normlaized toroidal magnetic field */ 3938 raymagnetic.dBzndY[0] = dBzdrho/B - Bz*dBdrho/B/B; 3939 raymagnetic.dBzndY[1] = dBzdtheta/B - Bz*dBdtheta/B/B; 3940 raymagnetic.dBzndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3941 3942 raymagnetic.B[0] = B;/* Total magnetic field */ 3943 raymagnetic.dBdY[0] = dBdrho; 3944 raymagnetic.dBdY[1] = dBdtheta; 3945 raymagnetic.dBdY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3946 3947 raymagnetic.rn[0] = r/equilparam.ap[0]; 3948 raymagnetic.drndY[0] = drdrho/equilparam.ap[0]; 3949 raymagnetic.drndY[1] = drdtheta/equilparam.ap[0]; 3950 raymagnetic.drndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3951 3952 raymagnetic.xn[0] = x/equilparam.ap[0]; 3953 raymagnetic.dxndY[0] = dxdrho/equilparam.ap[0]; 3954 raymagnetic.dxndY[1] = dxdtheta/equilparam.ap[0]; 3955 raymagnetic.dxndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3956 3957 raymagnetic.yn[0] = y/equilparam.ap[0]; 3958 raymagnetic.dyndY[0] = dydrho/equilparam.ap[0]; 3959 raymagnetic.dyndY[1] = dydtheta/equilparam.ap[0]; 3960 raymagnetic.dyndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3961 3962 raymagnetic.calpha[0] = calpha; 3963 raymagnetic.dcalphadY[0] = dcalphadrho; 3964 raymagnetic.dcalphadY[1] = dcalphadtheta; 3965 raymagnetic.dcalphadY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3966 3967 raymagnetic.salpha[0] = salpha; 3968 raymagnetic.dsalphadY[0] = dsalphadrho; 3969 raymagnetic.dsalphadY[1] = dsalphadtheta; 3970 raymagnetic.dsalphadY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3971 3972 raymagnetic.gradrhon[0] = gradrho*equilparam.ap[0]; 3973 raymagnetic.dgradrhondY[0] = dgradrhodrho*equilparam.ap[0]; 3974 raymagnetic.dgradrhondY[1] = dgradrhodtheta*equilparam.ap[0]; 3975 raymagnetic.dgradrhondY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3976 3977 raymagnetic.Upsilonn[0] = Upsilon/equilparam.ap[0]; 3978 raymagnetic.dUpsilonndY[0] = dUpsilondrho/equilparam.ap[0]; 3979 raymagnetic.dUpsilonndY[1] = dUpsilondtheta/equilparam.ap[0]; 3980 raymagnetic.dUpsilonndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3981 3982 raymagnetic.rhorip[0] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3983 raymagnetic.drhoripdY[0] = 1.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3984 raymagnetic.drhoripdY[1] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3985 raymagnetic.drhoripdY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 3986 } 3987 else/*Cartesian case*/ 3988 { 3989 /*-----Declaration of the derivatives needed for the chain rule operation----*/ 3990 3991 double theta = atan2(y,x);/*Analytical expression of theta(x,y)*/ 3992 3993 double calpha_theta = calpha*cos(theta) + salpha*sin(theta);/*cos(alpha-theta)*/ 3994 double salpha_theta = salpha*cos(theta) - calpha*sin(theta);/*sin(alpha-theta)*/ 3995 3996 double drhodx = gradrho*equilparam.ap[0]*calpha_theta;/*drhodx for the change of variable (rho,theta)->(x,y)*/ 3997 double drhody = -gradrho*equilparam.ap[0]*salpha_theta;/*drhody for the change of variable (rho,theta)->(x,y)*/ 3998 double dthetadx = -sin(theta)*equilparam.ap[0]/r;/*dthetadx for the change of variable (rho,theta)->(x,y)*/ 3999 double dthetady = cos(theta)*equilparam.ap[0]/r;/*dthetady for the change of variable (rho,theta)->(x,y)*/ 4000 4001 /*-Declaration of the cartesian equilibrium function and their derivatives-*/ 4002 4003 raymagnetic.Brhon[0] = 0.0;/* Normalized radial magnetic field */ 4004 raymagnetic.dBrhondY[0] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4005 raymagnetic.dBrhondY[1] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4006 raymagnetic.dBrhondY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4007 4008 raymagnetic.Bsn[0] = BP/B;/* Normalized poloidal magnetic field */ 4009 raymagnetic.dBsndY[0] = drhodx*(dBPdrho/B - BP*dBdrho/B/B) + dthetadx*(dBPdtheta/B - BP*dBdtheta/B/B); 4010 raymagnetic.dBsndY[1] = drhody*(dBPdrho/B - BP*dBdrho/B/B) + dthetady*(dBPdtheta/B - BP*dBdtheta/B/B); 4011 raymagnetic.dBsndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4012 4013 raymagnetic.Bzn[0] = Bz/B;/* Normlaized toroidal magnetic field */ 4014 raymagnetic.dBzndY[0] = drhodx*(dBzdrho/B - Bz*dBdrho/B/B) + dthetadx*(dBzdtheta/B - Bz*dBdtheta/B/B); 4015 raymagnetic.dBzndY[1] = drhody*(dBzdrho/B - Bz*dBdrho/B/B) + dthetady*(dBzdtheta/B - Bz*dBdtheta/B/B); 4016 raymagnetic.dBzndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4017 4018 raymagnetic.B[0] = B;/* Total magnetic field */ 4019 raymagnetic.dBdY[0] = drhodx*dBdrho + dthetadx*dBdtheta; 4020 raymagnetic.dBdY[1] = drhody*dBdrho + dthetady*dBdtheta; 4021 raymagnetic.dBdY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4022 4023 raymagnetic.rn[0] = r/equilparam.ap[0]; 4024 raymagnetic.drndY[0] = drhodx*drdrho/equilparam.ap[0] + dthetadx*drdtheta/equilparam.ap[0]; 4025 raymagnetic.drndY[1] = drhody*drdrho/equilparam.ap[0] + dthetady*drdtheta/equilparam.ap[0]; 4026 raymagnetic.drndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4027 4028 raymagnetic.xn[0] = x/equilparam.ap[0]; 4029 raymagnetic.dxndY[0] = drhodx*dxdrho/equilparam.ap[0] + dthetadx*dxdtheta/equilparam.ap[0]; 4030 raymagnetic.dxndY[1] = drhody*dxdrho/equilparam.ap[0] + dthetady*dxdtheta/equilparam.ap[0]; 4031 raymagnetic.dxndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4032 4033 raymagnetic.yn[0] = y/equilparam.ap[0]; 4034 raymagnetic.dyndY[0] = drhodx*dydrho/equilparam.ap[0] + dthetadx*dydtheta/equilparam.ap[0]; 4035 raymagnetic.dyndY[1] = drhody*dydrho/equilparam.ap[0] + dthetady*dydtheta/equilparam.ap[0]; 4036 raymagnetic.dyndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4037 4038 raymagnetic.calpha[0] = calpha; 4039 raymagnetic.dcalphadY[0] = drhodx*dcalphadrho + dthetadx*dcalphadtheta; 4040 raymagnetic.dcalphadY[1] = drhody*dcalphadrho + dthetady*dcalphadtheta; 4041 raymagnetic.dcalphadY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4042 4043 raymagnetic.salpha[0] = salpha; 4044 raymagnetic.dsalphadY[0] = drhodx*dsalphadrho + dthetadx*dsalphadtheta; 4045 raymagnetic.dsalphadY[1] = drhody*dsalphadrho + dthetady*dsalphadtheta; 4046 raymagnetic.dsalphadY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4047 4048 raymagnetic.gradrhon[0] = gradrho*equilparam.ap[0]; 4049 raymagnetic.dgradrhondY[0] = (drhodx*dgradrhodrho*equilparam.ap[0] + dthetadx*dgradrhodtheta*equilparam.ap[0]); 4050 raymagnetic.dgradrhondY[1] = (drhody*dgradrhodrho*equilparam.ap[0] + dthetady*dgradrhodtheta*equilparam.ap[0]); 4051 raymagnetic.dgradrhondY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4052 4053 raymagnetic.Upsilonn[0] = Upsilon/equilparam.ap[0]; 4054 raymagnetic.dUpsilonndY[0] = drhodx*(dUpsilondrho/equilparam.ap[0]) + dthetadx*(dUpsilondtheta/equilparam.ap[0]); 4055 raymagnetic.dUpsilonndY[1] = drhody*(dUpsilondrho/equilparam.ap[0]) + dthetady*(dUpsilondtheta/equilparam.ap[0]); 4056 raymagnetic.dUpsilonndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4057 4058 raymagnetic.rhorip[0] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4059 raymagnetic.drhoripdY[0] = drhodx;/* the unperturbed magnetic equilibrium is axisymmetric */ 4060 raymagnetic.drhoripdY[1] = drhody;/* the unperturbed magnetic equilibrium is axisymmetric */ 4061 raymagnetic.drhoripdY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4062 } 4063 4064 /* 4065 mexPrintf("rn[0],drndY[0],drndY[1],xn[0],dxndY[0],dxndY[1],yn[0],dyndY[0],dyndY[1]:%g,%g,%g,%g,%g,%g,%g,%g,%g\n",raymagnetic.rn[0],raymagnetic.drndY[0],raymagnetic.drndY[1],raymagnetic.xn[0],raymagnetic.dxndY[0],raymagnetic.dxndY[1],raymagnetic.yn[0],raymagnetic.dyndY[0],raymagnetic.dyndY[1]); 4066 mexPrintf("Bsn[0],dBsndY[0],dBsndY[1]:%g,%g,%g\n",raymagnetic.Bsn[0],raymagnetic.dBsndY[0],raymagnetic.dBsndY[1]); 4067 mexPrintf("Bzn[0],dBzndY[0],dBzndY[1]:%g,%g,%g\n",raymagnetic.Bzn[0],raymagnetic.dBzndY[0],raymagnetic.dBzndY[1]); 4068 mexPrintf("B[0],dBdY[0],dBdY[1]:%g,%g,%g\n",raymagnetic.B[0],raymagnetic.dBdY[0],raymagnetic.dBdY[1]); 4069 mexPrintf("salpha[0],dsalphadY[0],dsalphadY[1]:%g,%g,%g\n",raymagnetic.salpha[0],raymagnetic.dsalphadY[0],raymagnetic.dsalphadY[1]); 4070 mexPrintf("calpha[0],dcalphadY[0],dcalphadY[1]:%g,%g,%g\n",raymagnetic.calpha[0],raymagnetic.dcalphadY[0],raymagnetic.dcalphadY[1]); 4071 mexPrintf("gradrhon[0],dgradrhondY[0],dgradrhondY[1]:%g,%g,%g\n",raymagnetic.gradrhon[0],raymagnetic.dgradrhondY[0],raymagnetic.dgradrhondY[1]); 4072 mexPrintf("psia_apRp:%g,%g,%g\n",equilparam.psia_apRp[0]); 4073 mexPrintf("Upsilon,dUpsilondrho,dUpsilondtheta:%g,%g,%g\n",Upsilon,dUpsilondrho,dUpsilondtheta); 4074 */ 4075 } 4076 4077 void interpequil_test(raymagnetic,rayprofiles,equilparam,Y,flag)/*Doesn't have to be modified under a change of metric*/ 4078 raymagnetic_format raymagnetic; 4079 rayprofiles_format rayprofiles; 4080 equilparam_format equilparam;/* is an output in this case, since nothing is used from MatLab */ 4081 double Y[]; 4082 double flag; 4083 { 4084 /* toroidal circular equilibrium from Bonoli and Ott, PoF 25, 359 (1982) */ 4085 4086 /* In this equilibrium the radial coordinate is psi = r/a. 4087 The Shafranov shift is neglected in first approximation. 4088 As a consequence, BT0 and BP0 are uniform. 4089 */ 4090 4091 double Te0,Tea,eTe; 4092 double ne0,nea,ene; 4093 double Ti0,Tia,eTi; 4094 double fi[3],zZi[4],zmi[4]; 4095 4096 double Zp,Rp,ap,rho,theta; 4097 double Bz0,BP0,dBP0dY1; 4098 double B,dBdrho,dBdtheta; 4099 double BP,dBPdrho,dBPdtheta; 4100 double Bz,dBzdrho,dBzdtheta; 4101 double x,dxdrho,dxdtheta; 4102 double y,dydrho,dydtheta; 4103 double Zeff0,Zeffa,eZeff,pZeff,dpZeffdrho; 4104 double lambda; 4105 4106 double Ip,BPa,eq,qmin_Rpap,qmax_Rpap,q_Rpap,dqdrho_Rpap; 4107 4108 double Upsilon,dUpsilondrho,dUpsilondtheta; 4109 4110 int is,ns; 4111 4112 rho = Y[0]; 4113 theta = Y[1]; 4114 4115 load_idealequil_test(flag,&Zp,&Rp,&ap,&Bz0,&Ip,&eq,&qmin_Rpap,&Te0,&Tea,&eTe,&ne0,&nea,&ene,&Ti0,&Tia,&eTi,&Zeff0,&Zeffa,&eZeff,&ns,fi,zZi,zmi,&lambda); 4116 4117 /* 4118 mexPrintf("ap,Rp,Zp,Bz0,Ip,eq,qmin_Rpap,Te0,Tea,eTe,ne0,nea,ene,Ti0,Tia,eTi,Zeff0,Zeffa,eZeff,lambda=%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g\n",ap,Rp,Zp,Bz0,Ip,eq,qmin_Rpap,Te0,Tea,eTe,ne0,nea,ene,Ti0,Tia,eTi,Zeff0,Zeffa,eZeff,lambda); 4119 mexPrintf("ns,fi[0],fi[1],fi[2],zZi[0],zZi[1],zZi[2],zmi[0],zmi[1],zmi[2]=%d,%g,%g,%g,%g,%g,%g,%g,%g,%g\n",ns,fi[0],fi[1],fi[2],zZi[0],zZi[1],zZi[2],zmi[0],zmi[1],zmi[2]); 4120 */ 4121 4122 4123 if (zZi[0] > 0) {/*Vacuum case otherwise (no density, temperature...)*/ 4124 4125 pZeff = Zeff0 + (Zeffa-Zeff0)*pow(rho,eZeff); 4126 dpZeffdrho = eZeff*(Zeffa-Zeff0)*pow(rho,eZeff-1); 4127 4128 if (ns > 4) { 4129 mexErrMsgTxt("Only one fully stripped impurity can be used !"); 4130 } 4131 4132 /* 4133 double *d2TedY2; 4134 double *d2nedY2; 4135 double **d2zTidY2; 4136 double **d2znidY2; 4137 */ 4138 4139 4140 if ((fabs(flag) == 1) || (fabs(flag) == 2) || (fabs(flag) == 5) || (fabs(flag) == 6)) {/*Jetlike, RTtest, TORLH, RFP Madison*/ 4141 4142 rayprofiles.Te[0] = Tea + (Te0 - Tea)*pow(1 - rho*rho,eTe); 4143 rayprofiles.dTedY[0] = -2*rho*eTe*(Te0 - Tea)*pow(1 - rho*rho,eTe - 1); 4144 rayprofiles.dTedY[1] = 0.0; 4145 rayprofiles.dTedY[2] = 0.0; 4146 4147 rayprofiles.ne[0] = nea + (ne0 - nea)*pow(1 - rho*rho,ene); 4148 rayprofiles.dnedY[0] = -2*rho*ene*(ne0 - nea)*pow(1 - rho*rho,ene - 1); 4149 rayprofiles.dnedY[1] = 0.0; 4150 rayprofiles.dnedY[2] = 0.0; 4151 4152 4153 for (is=0;is else if ((fabs(flag) == 3) || (fabs(flag) == 4)) {/*VERSATOR2 and PLT */ 4162 4163 rayprofiles.Te[0] = Tea + (Te0 - Tea)*(exp(-eTe*Y[0]*Y[0]) - exp(-eTe))/(1 - exp(-eTe)); 4164 rayprofiles.dTedY[0] = -2*eTe*Y[0]*(Te0 - Tea)*exp(-eTe*Y[0]*Y[0])/(1 - exp(-eTe)); 4165 rayprofiles.dTedY[1] = 0.0; 4166 rayprofiles.dTedY[2] = 0.0; 4167 4168 rayprofiles.ne[0] = nea + (ne0 - nea)*(exp(ene) - exp(ene*Y[0]*Y[0]))/(exp(ene) - 1); 4169 rayprofiles.dnedY[0] = -2*ene*Y[0]*(ne0 - nea)*exp(ene*Y[0]*Y[0])/(exp(ene) - 1); 4170 rayprofiles.dnedY[1] = 0.0; 4171 rayprofiles.dnedY[2] = 0.0; 4172 4173 for (is=0;is for (is=0;is<3;is++) { /*For a single impurity fully stripped. Only the first is selected after the isotope of hydrogen */ 4182 rayprofiles.zni[is] = fi[is]*rayprofiles.ne[0]*(equilparam.zZi[3] - pZeff)/(equilparam.zZi[3]-1.0); 4183 rayprofiles.dznidY[is][0] = fi[is]*(rayprofiles.dnedY[0]*(equilparam.zZi[3] - pZeff) - rayprofiles.ne[0]*dpZeffdrho)/(equilparam.zZi[3]-1.0); 4184 rayprofiles.dznidY[is][1] = 0.0; 4185 rayprofiles.dznidY[is][2] = 0.0; 4186 } 4187 4188 for (is=3;is /*For a single impurity fully stripped. Only the first is selected after the isotope of hydrogen */ 4189 rayprofiles.zni[is] = rayprofiles.ne[0]*(pZeff - 1.0)/(equilparam.zZi[3]-1)/equilparam.zZi[3]; 4190 rayprofiles.dznidY[is][0] = (rayprofiles.dnedY[0]*(pZeff - 1.0) + rayprofiles.ne[0]*dpZeffdrho)/(equilparam.zZi[3]-1)/equilparam.zZi[3]; 4191 rayprofiles.dznidY[is][1] = 0.0; 4192 rayprofiles.dznidY[is][2] = 0.0; 4193 } 4194 4195 } 4196 4197 for (is=0;is if (isinf(equilparam.Rp[0]) == 1) {/* Toroidal factor. If Upsilon=1, cylindrical magnetic configuration */ 4218 Upsilon = 1.0; 4219 dUpsilondrho = 0.0; 4220 dUpsilondtheta = 0.0; 4221 } else { 4222 Upsilon = 1.0 + x/Rp; 4223 dUpsilondrho = dxdrho/Rp; 4224 dUpsilondtheta = dxdtheta/Rp; 4225 } 4226 4227 raymagnetic.xn[0] = x/ap; 4228 raymagnetic.dxndY[0] = dxdrho/ap; 4229 raymagnetic.dxndY[1] = dxdtheta/ap; 4230 raymagnetic.dxndY[2] = 0.0; 4231 4232 y = ap*rho*sin(theta); 4233 dydrho = ap*sin(theta); 4234 dydtheta = ap*rho*cos(theta); 4235 4236 raymagnetic.yn[0] = y/ap; 4237 raymagnetic.dyndY[0] = dydrho/ap; 4238 raymagnetic.dyndY[1] = dydtheta/ap; 4239 raymagnetic.dyndY[2] = 0.0; 4240 4241 BPa = 0.2*fabs(Ip)/ap;/* MA */ 4242 qmax_Rpap = fabs(Bz0)/BPa;/* cylindrical limit -> qmax*(Rp/ap)*/ 4243 4244 if ((fabs(flag) == 1) || (fabs(flag) == 3) ||(fabs(flag) == 4) || (fabs(flag) == 5)) {/*RTtest, VERSATOR2, PLT and TORLH */ 4245 4246 q_Rpap = (qmax_Rpap - qmin_Rpap)*pow(Y[0],eq) + qmin_Rpap; 4247 dqdrho_Rpap = eq*(qmax_Rpap - qmin_Rpap)*pow(Y[0],eq - 1.0); 4248 4249 equilparam.psia_apRp[0] = ap*ap*fabs(Bz0)*log(qmax_Rpap/qmin_Rpap)/(qmax_Rpap - qmin_Rpap)/2; 4250 4251 } else if (fabs(flag) == 2) {/*JETlike */ 4252 4253 if (Y[0] == 0.0) { 4254 q_Rpap = qmax_Rpap/(1+eq); 4255 dqdrho_Rpap = 0.0; 4256 } else { 4257 q_Rpap = qmax_Rpap*pow(Y[0],2)/(1 - pow(1-Y[0]*Y[0],1+eq)); 4258 dqdrho_Rpap = 2*q_Rpap*(1 - (eq+1)*pow(1-Y[0]*Y[0],eq)*q_Rpap/qmax_Rpap)/Y[0]; 4259 } 4260 4261 equilparam.psia_apRp[0] = ap*ap*BPa*3/4; 4262 4263 } else if (fabs(flag) == 6) {/*RFP Madison */ 4264 4265 q_Rpap = Y[0]*j0(lambda*Y[0])/j1(lambda*Y[0]); 4266 dqdrho_Rpap = j0(lambda*Y[0])/j1(lambda*Y[0]) - lambda*Y[0] - j0(lambda*Y[0])*(j0(lambda*Y[0]) - lambda*Y[0]*jn(2,lambda*Y[0]))/j1(lambda*Y[0])/j1(lambda*Y[0]); 4267 4268 equilparam.psia_apRp[0] = ap*ap*fabs(Bz0)*(1.0 - j0(lambda*Y[0]))/lambda; 4269 } 4270 4271 /* mexPrintf("qmax_Rpap,BPa,equilparam.psia_apRp[0] = %g,%g,%g\n",qmax_Rpap,BPa,equilparam.psia_apRp[0]);*/ 4272 4273 4274 if (lambda == 0) {/* tokamak */ 4275 4276 Bz = Bz0/Upsilon; 4277 dBzdrho = -Bz0*dUpsilondrho/Upsilon/Upsilon; 4278 dBzdtheta = -Bz0*dUpsilondtheta/Upsilon/Upsilon; 4279 4280 BP = qmax_Rpap*BPa*Y[0]/q_Rpap/Upsilon;/* Poloidal magnetic field, cylindrical limit */ 4281 dBPdrho = qmax_Rpap*BPa*(1.0 - dqdrho_Rpap*Y[0]/q_Rpap - dUpsilondrho*Y[0]/Upsilon)/q_Rpap/Upsilon; 4282 dBPdtheta = -BP*dUpsilondtheta/Upsilon; 4283 4284 } else {/* RFP */ 4285 4286 Bz = fabs(Bz0)*j0(lambda*Y[0])/Upsilon; 4287 dBzdrho = -fabs(Bz0)*lambda*j1(lambda*Y[0])/Upsilon - fabs(Bz0)*j0(lambda*Y[0])*dUpsilondrho/Upsilon/Upsilon; 4288 dBzdtheta = -Bz*dUpsilondtheta/Upsilon; 4289 4290 BP = fabs(Bz0)*j1(lambda*Y[0])/Upsilon; 4291 dBPdrho = fabs(Bz0)*lambda*(j0(lambda*Y[0]) - jn(2,lambda*Y[0]))/Upsilon/2 - fabs(Bz0)*j1(lambda*Y[0])*dUpsilondrho/Upsilon/Upsilon; 4292 dBPdtheta = -BP*dUpsilondtheta/Upsilon; 4293 } 4294 4295 /* mexPrintf("ap,Rp,BPa,rho,BP,Bz0,x,theta,dBPdrho,dBPdtheta:%g,%g,%g,%g,%g,%g,%g,%g,%g,%g\n",ap,Rp,BPa,rho,theta,BP,Bz0,x,dBPdrho,dBPdtheta);*/ 4296 4297 B = sqrt(BP*BP + Bz*Bz); 4298 dBdrho = (BP*dBPdrho + Bz*dBzdrho)/B; 4299 dBdtheta = (BP*dBPdtheta + Bz*dBzdtheta)/B; 4300 4301 raymagnetic.Brhon[0] = 0.0;/* Normalized radial magnetic field */ 4302 raymagnetic.dBrhondY[0] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4303 raymagnetic.dBrhondY[1] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4304 raymagnetic.dBrhondY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4305 4306 raymagnetic.Bzn[0] = Bz/B; 4307 raymagnetic.dBzndY[0] = dBzdrho/B - Bz*dBdrho/B/B; 4308 raymagnetic.dBzndY[1] = dBzdtheta/B - Bz*dBdtheta/B/B; 4309 raymagnetic.dBzndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4310 4311 raymagnetic.Bsn[0] = BP/B; 4312 raymagnetic.dBsndY[0] = dBPdrho/B - BP*dBdrho/B/B; 4313 raymagnetic.dBsndY[1] = dBPdtheta/B - BP*dBdtheta/B/B; 4314 raymagnetic.dBsndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4315 4316 raymagnetic.B[0] = B; 4317 raymagnetic.dBdY[0] = dBdrho; 4318 raymagnetic.dBdY[1] = dBdtheta; 4319 raymagnetic.dBdY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4320 4321 raymagnetic.calpha[0] = 1.0; 4322 raymagnetic.dcalphadY[0] = 0.0; 4323 raymagnetic.dcalphadY[1] = 0.0; 4324 raymagnetic.dcalphadY[2] = 0.0; 4325 4326 raymagnetic.salpha[0] = 0.0; 4327 raymagnetic.dsalphadY[0] = 0.0; 4328 raymagnetic.dsalphadY[1] = 0.0; 4329 raymagnetic.dsalphadY[2] = 0.0; 4330 4331 raymagnetic.gradrhon[0] = 1.0; 4332 raymagnetic.dgradrhondY[0] = 0.0; 4333 raymagnetic.dgradrhondY[1] = 0.0; 4334 raymagnetic.dgradrhondY[2] = 0.0; 4335 4336 raymagnetic.rhorip[0] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4337 raymagnetic.drhoripdY[0] = 1.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4338 raymagnetic.drhoripdY[1] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4339 raymagnetic.drhoripdY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4340 4341 raymagnetic.Upsilonn[0] = Upsilon/ap; 4342 raymagnetic.dUpsilonndY[0] = dUpsilondrho/ap; 4343 raymagnetic.dUpsilonndY[1] = dUpsilondtheta/ap; 4344 raymagnetic.dUpsilonndY[2] = 0.0;/* the unperturbed magnetic equilibrium is axisymmetric */ 4345 4346 /* 4347 4348 mexPrintf("---- Interpequil_test ----\n"); 4349 mexPrintf("rho,theta:%g,%g\n",rho,theta); 4350 mexPrintf("Te[0],dTedY[0],dTedY[1],ne[0],dnedY[0],dnedY[1]:%g,%g,%g,%g,%g,%g\n",rayprofiles.Te[0],rayprofiles.dTedY[0],rayprofiles.dTedY[1],rayprofiles.ne[0],rayprofiles.dnedY[0],rayprofiles.dnedY[1]); 4351 for (is=0;is<ns;is++) { 4352 mexPrintf("is,zTi[is],dzTidY[is][0],dzTidY[is][1],zni[is],dznidY[is][0],dznidY[is][1]:%d,%g,%g,%g,%g,%g,%g\n",is,rayprofiles.zTi[is],rayprofiles.dzTidY[is][0],rayprofiles.dzTidY[is][1],rayprofiles.zni[is],rayprofiles.dznidY[is][0],rayprofiles.dznidY[is][1]); 4353 } 4354 4355 mexPrintf("rn[0],drndY[0],drndY[1],xn[0],dxndY[0],dxndY[1],yn[0],dyndY[0],dyndY[1]:%15.10g,%15.10g,%15.10g,%15.10g,%15.10g,%15.10g,%15.10g,%15.10g,%15.10g\n",raymagnetic.rn[0],raymagnetic.drndY[0],raymagnetic.drndY[1],raymagnetic.xn[0],raymagnetic.dxndY[0],raymagnetic.dxndY[1],raymagnetic.yn[0],raymagnetic.dyndY[0],raymagnetic.dyndY[1]); 4356 mexPrintf("Bsn[0],dBsndY[0],dBsndY[1]:%15.10g,%15.10g,%15.10g\n",raymagnetic.Bsn[0],raymagnetic.dBsndY[0],raymagnetic.dBsndY[1]); 4357 mexPrintf("Bzn[0],dBzndY[0],dBzndY[1]:%15.10g,%15.10g,%15.10g\n",raymagnetic.Bzn[0],raymagnetic.dBzndY[0],raymagnetic.dBzndY[1]); 4358 mexPrintf("B[0],dBdY[0],dBdY[1]:%15.10g,%15.10g,%15.10g\n",raymagnetic.B[0],raymagnetic.dBdY[0],raymagnetic.dBdY[1]); 4359 mexPrintf("salpha[0],dsalphadY[0],dsalphadY[1]:%15.10g,%15.10g,%15.10g\n",raymagnetic.salpha[0],raymagnetic.dsalphadY[0],raymagnetic.dsalphadY[1]); 4360 mexPrintf("calpha[0],dcalphadY[0],dcalphadY[1]:%15.10g,%15.10g,%15.10g\n",raymagnetic.calpha[0],raymagnetic.dcalphadY[0],raymagnetic.dcalphadY[1]); 4361 mexPrintf("gradrhon[0],dgradrhondY[0],dgradrhondY[1]:%15.10g,%15.10g,%15.10g\n",raymagnetic.gradrhon[0],raymagnetic.dgradrhondY[0],raymagnetic.dgradrhondY[1]); 4362 4363 */ 4364 4365 } 4366 4367 4368 double sgn(x) 4369 double x; 4370 { 4371 if (x < 0.0) {return(-1.0);} 4372 else if (x == 0.0) {return(0.0);} 4373 else {return(1.0);} 4374 4375 } 4376 4377 4378 void load_idealequil_test(flag,Zp,Rp,ap,Bz0,Ip,eq,qmin_Rpap,Te0,Tea,eTe,ne0,nea,ene,Ti0,Tia,eTi,Zeff0,Zeffa,eZeff,ns,fi,zZi,zmi,lambda) 4379 double *Zp,*Rp,*ap,*Bz0,*Ip,*eq,*qmin_Rpap,*Te0,*Tea,*eTe,*ne0,*nea,*ene,*Ti0,*Tia,*eTi,*Zeff0,*Zeffa,*eZeff,*lambda; 4380 double fi[],zZi[],zmi[]; 4381 double flag; 4382 int *ns; 4383 { 4384 4385 4386 if (fabs(flag) == 1) {/* RTtest case */ 4387 4388 Rp[0] = 3.0; 4389 Zp[0] = 0; 4390 ap[0] = 0.9; 4391 Bz0[0] = 3.0;/* Signed toroidal magnetic component (T), see the conventions */ 4392 Ip[0] = 1.0;/* Signed toroidal component of the plasma current (MA), see the conventions */ 4393 qmin_Rpap[0] = 1.0*Rp[0]/ap[0];/* Edge safety factor q */ 4394 eq[0] = 2.0;/* q=0 flat q profile */ 4395 4396 lambda[0] = 0;/* BFM magnetic equilbrium model for RFP */ 4397 4398 Te0[0] = 4.0; 4399 Tea[0] = Te0[0]/10.0; 4400 eTe[0] = 1.0; 4401 4402 ne0[0] = 3.0e+19; 4403 nea[0] = 1e-10; 4404 ene[0] = 1.0; 4405 4406 Ti0[0] = Te0[0]; 4407 Tia[0] = Tea[0]; 4408 eTi[0] = eTe[0]; 4409 4410 fi[0] = 1.0; 4411 fi[1] = 0.0; 4412 fi[2] = 0.0; 4413 4414 if (flag < 0) {/* vacuum case */ 4415 zZi[0] = 0.0; 4416 zZi[1] = 0.0; 4417 zZi[2] = 0.0; 4418 zZi[3] = 0.0;/* Carbon */ 4419 } else { 4420 zZi[0] = 1.0; 4421 zZi[1] = 1.0; 4422 zZi[2] = 1.0; 4423 zZi[3] = 6.0;/* Carbon */ 4424 } 4425 4426 zmi[0] = 1.0; 4427 zmi[1] = 2.0; 4428 zmi[2] = 3.0; 4429 zmi[3] = 12.0;/* Carbon */ 4430 4431 ns[0] = 4; 4432 4433 Zeff0[0] = 1.0;/* No impurity case, only hydrogen */ 4434 Zeffa[0] = 1.0; 4435 eZeff[0] = 0.0; 4436 4437 } else if (fabs(flag) == 2) {/* Jetlike case */ 4438 4439 Rp[0] = 3.05; 4440 Zp[0] = 0; 4441 ap[0] = 0.95; 4442 Bz0[0] = 3.2;/* Signed toroidal magnetic component (T), see the conventions */ 4443 Ip[0] = 3.5;/* Signed toroidal component of the plasma current (MA), see the conventions */ 4444 qmin_Rpap[0] = 1.0*Rp[0]/ap[0];/* Edge safety factor q */ 4445 eq[0] = 1.0;/* q=0 flat q profile */ 4446 4447 lambda[0] = 0;/* BFM magnetic equilbrium model for RFP */ 4448 4449 Te0[0] = 6.0; 4450 Tea[0] = 0.1; 4451 eTe[0] = 1.5; 4452 4453 ne0[0] = 5.0e+19; 4454 nea[0] = 0.01e+19; 4455 ene[0] = 1.0; 4456 4457 Ti0[0] = Te0[0]; 4458 Tia[0] = Tea[0]; 4459 eTi[0] = eTe[0]; 4460 4461 fi[0] = 1.0; 4462 fi[1] = 0.0; 4463 fi[2] = 0.0; 4464 4465 zZi[0] = 1.0; 4466 zZi[1] = 1.0; 4467 zZi[2] = 1.0; 4468 4469 zmi[0] = 1.0; 4470 zmi[1] = 2.0; 4471 zmi[2] = 3.0; 4472 4473 ns[0] = 3; 4474 4475 Zeff0[0] = 1.0;/* No impurity case, only hydrogen */ 4476 Zeffa[0] = 1.0; 4477 eZeff[0] = 0.0; 4478 4479 } else if (fabs(flag) == 3) {/* VERSATOR2 case */ 4480 4481 Rp[0] = 0.4; 4482 Zp[0] = 0; 4483 ap[0] = 0.325*0.4; 4484 Bz0[0] = 1.4;/* Signed toroidal magnetic component (T), see the conventions */ 4485 Ip[0] = 0.05;/* Signed toroidal component of the plasma current (MA), see the conventions */ 4486 qmin_Rpap[0] = 1.0*Rp[0]/ap[0];/* Edge safety factor q */ 4487 eq[0] = 2.0;/* q=0 flat q profile */ 4488 4489 lambda[0] = 0;/* BFM magnetic equilbrium model for RFP */ 4490 4491 Te0[0] = 0.40; 4492 Tea[0] = 0.02; 4493 eTe[0] = 3.94; 4494 4495 ne0[0] = 2.0e19; 4496 nea[0] = 2e18; 4497 ene[0] = 0.1; 4498 4499 Ti0[0] = 0.15; 4500 Tia[0] = 0.02; 4501 eTi[0] = 3.94; 4502 4503 fi[0] = 1.0; 4504 fi[1] = 0.0; 4505 fi[2] = 0.0; 4506 4507 zZi[0] = 1.0; 4508 zZi[1] = 1.0; 4509 zZi[2] = 1.0; 4510 zZi[3] = 6.0; 4511 4512 zmi[0] = 1.0; 4513 zmi[1] = 2.0; 4514 zmi[2] = 3.0; 4515 zmi[3] = 12.0; 4516 4517 ns[0] = 4; 4518 4519 Zeff0[0] = 2.0;/* No impurity case, only hydrogen */ 4520 Zeffa[0] = 2.0; 4521 eZeff[0] = 0.0; 4522 4523 } else if (fabs(flag) == 4) {/* PLT case */ 4524 4525 Rp[0] = 1.32; 4526 Zp[0] = 0; 4527 ap[0] = 0.303*1.32; 4528 Bz0[0] = 3.1;/* Signed toroidal magnetic component (T), see the conventions */ 4529 Ip[0] = 0.2;/* Signed toroidal component of the plasma current (MA), see the conventions */ 4530 qmin_Rpap[0] = 1.0*Rp[0]/ap[0];/* Edge safety factor q */ 4531 eq[0] = 2.0;/* q=0 flat q profile */ 4532 4533 lambda[0] = 0;/* BFM magnetic equilbrium model for RFP */ 4534 4535 Te0[0] = 1.5; 4536 Tea[0] = 0.03; 4537 eTe[0] = 3.99; 4538 4539 ne0[0] = 0.5625e19; 4540 nea[0] = 0.5625e18; 4541 ene[0] = -0.571; 4542 4543 Ti0[0] = 0.5; 4544 Tia[0] = 0.03; 4545 eTi[0] = 2.90; 4546 4547 fi[0] = 1.0; 4548 fi[1] = 0.0; 4549 fi[2] = 0.0; 4550 4551 zZi[0] = 1.0; 4552 zZi[1] = 1.0; 4553 zZi[2] = 1.0; 4554 zZi[3] = 6.0; 4555 4556 zmi[0] = 1.0; 4557 zmi[1] = 2.0; 4558 zmi[2] = 3.0; 4559 zmi[3] = 12.0; 4560 4561 ns[0] = 4; 4562 4563 Zeff0[0] = 4.0;/* No impurity case, only hydrogen */ 4564 Zeffa[0] = 4.0; 4565 eZeff[0] = 0.0; 4566 4567 } else if (fabs(flag) == 5) {/* TORLH comparison */ 4568 4569 Rp[0] = 2.96; 4570 Zp[0] = 0; 4571 ap[0] = 1.25; 4572 Bz0[0] = 3.45;/* Signed toroidal magnetic component (T), see the conventions */ 4573 Ip[0] = 2.276446368308309;/* Signed toroidal component of the plasma current (MA), see the conventions */ 4574 qmin_Rpap[0] = 1.0*Rp[0]/ap[0];/* Edge safety factor q */ 4575 eq[0] = 2.0;/* q=0 flat q profile */ 4576 4577 lambda[0] = 0;/* BFM magnetic equilbrium model for RFP */ 4578 4579 Te0[0] = 1.0; 4580 Tea[0] = 1.0; 4581 eTe[0] = 0.0; 4582 4583 ne0[0] = 3.0e19; 4584 nea[0] = 3.0e18; 4585 ene[0] = 1; 4586 4587 Ti0[0] = Te0[0]; 4588 Tia[0] = Tea[0]; 4589 eTi[0] = eTe[0]; 4590 4591 fi[0] = 0.0; 4592 fi[1] = 1.0; 4593 fi[2] = 0.0; 4594 4595 zZi[0] = 1.0; 4596 zZi[1] = 1.0; 4597 zZi[2] = 1.0; 4598 zZi[3] = 6.0; 4599 4600 zmi[0] = 1.0; 4601 zmi[1] = 2.0; 4602 zmi[2] = 3.0; 4603 zmi[3] = 12.0; 4604 4605 ns[0] = 4; 4606 4607 Zeff0[0] = 1.7;/* No impurity case, only hydrogen */ 4608 Zeffa[0] = 1.7; 4609 eZeff[0] = 0.0; 4610 4611 } else if (fabs(flag) == 6) {/* RFP madison comparison */ 4612 4613 Rp[0] = 1.50; 4614 Zp[0] = 0; 4615 ap[0] = 0.5; 4616 Bz0[0] = 0.2;/* Signed toroidal magnetic component (T), see the conventions */ 4617 Ip[0] = 0.3;/* Signed toroidal component of the plasma current (MA), see the conventions */ 4618 qmin_Rpap[0] = 0;/* Edge safety factor q */ 4619 eq[0] = 0;/* q=0 flat q profile */ 4620 4621 lambda[0] = 2.2;/* BFM magnetic equilbrium model for RFP */ 4622 4623 Te0[0] = 1.3; 4624 Tea[0] = 0.10*Te0[0]; 4625 eTe[0] = 1.1; 4626 4627 ne0[0] = 1.4e19; 4628 nea[0] = 0.24*ne0[0]; 4629 ene[0] = 1.3; 4630 4631 Ti0[0] = 0.35; 4632 Tia[0] = 0.1*Ti0[0]; 4633 eTi[0] = 1.1; 4634 4635 fi[0] = 0.0; 4636 fi[1] = 1.0; 4637 fi[2] = 0.0; 4638 4639 zZi[0] = 1.0; 4640 zZi[1] = 1.0; 4641 zZi[2] = 1.0; 4642 zZi[3] = 6.0; 4643 4644 zmi[0] = 1.0; 4645 zmi[1] = 2.0; 4646 zmi[2] = 3.0; 4647 zmi[3] = 12.0; 4648 4649 ns[0] = 4; 4650 4651 Zeff0[0] = 2.0;/* No impurity case, only hydrogen */ 4652 Zeffa[0] = 2.0; 4653 eZeff[0] = 0.0; 4654 } 4655 4656 4657 4658 4659 } 4660 4661 4662 void testparam(rayparam,equilparam,fluctparam,raymagnetic,rayprofiles,rayequil,rayfluctuations,distriparam,raydistri,flag_fluct,flag_f0,flag,y0_in) 4663 rayparam_format rayparam; 4664 equilparam_format equilparam; 4665 fluctparam_format fluctparam; 4666 raymagnetic_format raymagnetic; 4667 rayprofiles_format rayprofiles; 4668 rayequil_format rayequil; 4669 rayfluctuations_format rayfluctuations; 4670 distriparam_format distriparam; 4671 raydistri_format raydistri; 4672 int flag_fluct,flag_f0; 4673 double flag; 4674 double y0_in[MC]; 4675 { 4676 4677 double *Te,*ne,*zTi,*zni; 4678 double *dTedrho,*dnedrho,*dzTidrho,*dznidrho; 4679 double *d2Tedrho2,*d2nedrho2,*d2zTidrho2,*d2znidrho2; 4680 4681 double *Bx,*dBxdrho,*dBxdtheta,*d2Bxdtheta2,*d2Bxdthetadrho,*d2Bxdrho2; 4682 double *By,*dBydrho,*dBydtheta,*d2Bydtheta2,*d2Bydthetadrho,*d2Bydrho2; 4683 double *Bz,*dBzdrho,*dBzdtheta,*d2Bzdtheta2,*d2Bzdthetadrho,*d2Bzdrho2; 4684 4685 double *x,*dxdrho,*dxdtheta,*d2xdtheta2,*d2xdthetadrho,*d2xdrho2; 4686 double *y,*dydrho,*dydtheta,*d2ydtheta2,*d2ydthetadrho,*d2ydrho2; 4687 4688 double *L_rho; 4689 double *xq,*dxqdrho; 4690 double *xL_theta,*dxL_thetadrho; 4691 double *xL_perp,*dxL_perpdrho; 4692 double *XL_phi,*dXL_phidrho,*dXL_phidtheta; 4693 4694 double *sf,*dsfdrho,*dsfdtheta; 4695 double *sfx,*dsfxdrho,*dsfxdtheta; 4696 double *sfy,*dsfydrho,*dsfydtheta; 4697 double *sfz,*dsfzdrho,*dsfzdtheta; 4698 4699 double *f0_fit,*df0drho_fit,*d2f0drho2_fit; 4700 double *PSI_fit; 4701 int ip_ref,jm_ref; 4702 4703 double dummy1,dummy2,dummy3; 4704 4705 int jf,ip,jm; 4706 4707 double xm=-0.71,xp=0.71,ht,dht,d2ht; 4708 4709 double ytest[MC]; 4710 4711 if (flag == 0) {/* numerical toroidal MHD equilibrium */ 4712 if (equilparam.zZi[0] > 0) { 4713 mexPrintf("----------------------------------------\n"); 4714 mexPrintf("Te_fit.coefs_f(1): %g\n",rayequil.Te_fit.coefs_f[0]); 4715 mexPrintf("Te_fit.coefs_dfdrho(1): %g\n",rayequil.Te_fit.coefs_dfdrho[0]); 4716 mexPrintf("Te_fit.coefs_d2fdrho2(1): %g\n",rayequil.Te_fit.coefs_d2fdrho2[0]); 4717 } 4718 4719 mexPrintf("----------------------------------------\n"); 4720 mexPrintf("Bz_fit.nfourier: %g\n",rayequil.Bz_fit.dim_dbndrho[0]); 4721 mexPrintf("Bz_fit.coefs_bn(1): %g\n",rayequil.Bz_fit.coefs_bn[0]); 4722 mexPrintf("Bz_fit.coefs_dbndrho(1): %g\n",rayequil.Bz_fit.coefs_dbndrho[0]); 4723 4724 4725 if (equilparam.zZi[0] > 0) { 4726 mexPrintf("----------------------------------------\n"); 4727 Te = mxCalloc(1,sizeof(double)); 4728 dTedrho = mxCalloc(1,sizeof(double)); 4729 d2Tedrho2 = mxCalloc(1,sizeof(double)); 4730 ppvald_1D(rayequil.Te_fit,rayparam.dS[0],0.25,Te,dTedrho,d2Tedrho2); 4731 mexPrintf("Te(0.25),dTedrho(0.25),d2Tedrho2(0.25) (keV): %g,%g,%g\n",Te[0],dTedrho[0],d2Tedrho2[0]); 4732 mxFree(Te); 4733 mxFree(dTedrho); 4734 mxFree(d2Tedrho2); 4735 4736 ne = mxCalloc(1,sizeof(double)); 4737 dnedrho = mxCalloc(1,sizeof(double)); 4738 d2nedrho2 = mxCalloc(1,sizeof(double)); 4739 ppvald_1D(rayequil.ne_fit,rayparam.dS[0],0.25,ne,dnedrho,d2nedrho2); 4740 mexPrintf("ne(0.25),dnedrho(0.25),d2nedrho2(0.25) (10+19 m-3): %g,%g,%g\n",ne[0]/1e19,dnedrho[0]/1e19,d2nedrho2[0]/1e19); 4741 mxFree(ne); 4742 mxFree(dnedrho); 4743 mxFree(d2nedrho2); 4744 4745 zTi = mxCalloc(equilparam.ns[0],sizeof(double)); 4746 dzTidrho = mxCalloc(equilparam.ns[0],sizeof(double)); 4747 d2zTidrho2 = mxCalloc(equilparam.ns[0],sizeof(double)); 4748 ppvald_1D(rayequil.zTi_fit,rayparam.dS[0],0.25,zTi,dzTidrho,d2zTidrho2); 4749 mexPrintf("zTi(2,0.25),dzTidrho(2,0.25),d2zTidrho2(2,0.25) (keV): %g,%g,%g\n",zTi[0],dzTidrho[0],d2zTidrho2[0]); 4750 mxFree(zTi); 4751 mxFree(dzTidrho); 4752 mxFree(d2zTidrho2); 4753 4754 zni = mxCalloc(equilparam.ns[0],sizeof(double)); 4755 dznidrho = mxCalloc(equilparam.ns[0],sizeof(double)); 4756 d2znidrho2 = mxCalloc(equilparam.ns[0],sizeof(double)); 4757 ppvald_1D(rayequil.zni_fit,rayparam.dS[0],0.25,zni,dznidrho,d2znidrho2); 4758 mexPrintf("zni(2,0.25),dznidrho(2,0.25),d2znidrho2(2,0.25) (10+19 m-3): %g,%g,%g\n",zni[0]/1e19,dznidrho[0]/1e19,d2znidrho2[0]/1e19); 4759 mxFree(zni); 4760 mxFree(dznidrho); 4761 mxFree(d2znidrho2); 4762 } 4763 4764 mexPrintf("----------------------------------------\n"); 4765 x = mxCalloc(1,sizeof(double)); 4766 dxdrho = mxCalloc(1,sizeof(double)); 4767 dxdtheta = mxCalloc(1,sizeof(double)); 4768 d2xdtheta2 = mxCalloc(1,sizeof(double)); 4769 d2xdthetadrho = mxCalloc(1,sizeof(double)); 4770 d2xdrho2 = mxCalloc(1,sizeof(double)); 4771 ppvald_2D(rayequil.x_fit,rayparam.dS[0],0.25,0.2,x,dxdrho,dxdtheta,d2xdtheta2,d2xdthetadrho,d2xdrho2); 4772 mexPrintf("x(0.25,0.2),dxdrho(0.25,0.2),dxdtheta(0.25,0.2) (m): %g,%g,%g\n",x[0],dxdrho[0],dxdtheta[0],d2xdtheta2[0],d2xdthetadrho[0]); 4773 mexPrintf("d2xdthetadrho(0.25,0.2),d2xdtheta2(0.25,0.2),d2xdrho2(0.25,0.2) (m): %g,%g,%g\n",d2xdthetadrho[0],d2xdtheta2[0],d2xdrho2[0]); 4774 mxFree(x); 4775 mxFree(dxdrho); 4776 mxFree(dxdtheta); 4777 mxFree(d2xdtheta2); 4778 mxFree(d2xdthetadrho); 4779 mxFree(d2xdrho2); 4780 4781 y = mxCalloc(1,sizeof(double)); 4782 dydrho = mxCalloc(1,sizeof(double)); 4783 dydtheta = mxCalloc(1,sizeof(double)); 4784 d2ydtheta2 = mxCalloc(1,sizeof(double)); 4785 d2ydthetadrho = mxCalloc(1,sizeof(double)); 4786 d2ydrho2 = mxCalloc(1,sizeof(double)); 4787 ppvald_2D(rayequil.y_fit,rayparam.dS[0],0.25,0.2,y,dydrho,dydtheta,d2ydtheta2,d2ydthetadrho,d2ydrho2); 4788 mexPrintf("y(0.25,0.2),dydrho(0.25,0.2),dydtheta(0.25,0.2) (m): %g,%g,%g\n",y[0],dydrho[0],dydtheta[0],d2ydtheta2[0],d2ydthetadrho[0]); 4789 mexPrintf("d2ydthetadrho(0.25,0.2),d2ydtheta2(0.25,0.2),d2ydrho2(0.25,0.2) (m): %g,%g,%g\n",d2ydthetadrho[0],d2ydtheta2[0],d2ydrho2[0]); 4790 mxFree(y); 4791 mxFree(dydrho); 4792 mxFree(dydtheta); 4793 mxFree(d2ydtheta2); 4794 mxFree(d2ydthetadrho); 4795 mxFree(d2ydrho2); 4796 4797 Bx = mxCalloc(1,sizeof(double)); 4798 dBxdrho = mxCalloc(1,sizeof(double)); 4799 dBxdtheta = mxCalloc(1,sizeof(double)); 4800 d2Bxdtheta2 = mxCalloc(1,sizeof(double)); 4801 d2Bxdthetadrho = mxCalloc(1,sizeof(double)); 4802 d2Bxdrho2 = mxCalloc(1,sizeof(double)); 4803 ppvald_2D(rayequil.Bx_fit,rayparam.dS[0],0.25,0.2,Bx,dBxdrho,dBxdtheta,d2Bxdtheta2,d2Bxdthetadrho,d2Bxdrho2); 4804 mexPrintf("Bx(0.25,0.2),dBxdrho(0.25,0.2),dBxdtheta(0.25,0.2) (T): %g,%g,%g\n",Bx[0],dBxdrho[0],dBxdtheta[0]); 4805 mexPrintf("d2Bxdthetadrho(0.25,0.2),d2Bxdtheta2(0.25,0.2),d2Bxdrho2(0.25,0.2) (m): %g,%g,%g\n",d2Bxdthetadrho[0],d2Bxdtheta2[0],d2Bxdrho2[0]); 4806 mxFree(Bx); 4807 mxFree(dBxdrho); 4808 mxFree(dBxdtheta); 4809 mxFree(d2Bxdtheta2); 4810 mxFree(d2Bxdthetadrho); 4811 mxFree(d2Bxdrho2); 4812 4813 By = mxCalloc(1,sizeof(double)); 4814 dBydrho = mxCalloc(1,sizeof(double)); 4815 dBydtheta = mxCalloc(1,sizeof(double)); 4816 d2Bydtheta2 = mxCalloc(1,sizeof(double)); 4817 d2Bydthetadrho = mxCalloc(1,sizeof(double)); 4818 d2Bydrho2 = mxCalloc(1,sizeof(double)); 4819 ppvald_2D(rayequil.By_fit,rayparam.dS[0],0.25,0.2,By,dBydrho,dBydtheta,d2Bydtheta2,d2Bydthetadrho,d2Bydrho2); 4820 mexPrintf("By(0.25,0.2),dBydrho(0.25,0.2),dBydtheta(0.25,0.2) (T): %g,%g,%g\n",By[0],dBydrho[0],dBydtheta[0]); 4821 mexPrintf("d2Bydthetadrho(0.25,0.2),d2Bydtheta2(0.25,0.2),d2Bydrho2(0.25,0.2) (m): %g,%g,%g\n",d2Bydthetadrho[0],d2Bydtheta2[0],d2Bydrho2[0]); 4822 mxFree(By); 4823 mxFree(dBydrho); 4824 mxFree(dBydtheta); 4825 mxFree(d2Bydtheta2); 4826 mxFree(d2Bydthetadrho); 4827 mxFree(d2Bydrho2); 4828 4829 Bz = mxCalloc(1,sizeof(double)); 4830 dBzdrho = mxCalloc(1,sizeof(double)); 4831 dBzdtheta = mxCalloc(1,sizeof(double)); 4832 d2Bzdtheta2 = mxCalloc(1,sizeof(double)); 4833 d2Bzdthetadrho = mxCalloc(1,sizeof(double)); 4834 d2Bzdrho2 = mxCalloc(1,sizeof(double)); 4835 ppvald_2D(rayequil.Bz_fit,rayparam.dS[0],0.25,0.2,Bz,dBzdrho,dBzdtheta,d2Bzdtheta2,d2Bzdthetadrho,d2Bzdrho2); 4836 mexPrintf("Bz(0.25,0.2),dBzdrho(0.25,0.2),dBzdtheta(0.25,0.2) (T): %g,%g,%g\n",Bz[0],dBzdrho[0],dBzdtheta[0]); 4837 mexPrintf("d2Bzdthetadrho(0.25,0.2),d2Bzdtheta2(0.25,0.2),d2Bzdrho2(0.25,0.2) (m): %g,%g,%g\n",d2Bzdthetadrho[0],d2Bzdtheta2[0],d2Bzdrho2[0]); 4838 mxFree(Bz); 4839 mxFree(dBzdrho); 4840 mxFree(dBzdtheta); 4841 mxFree(d2Bzdtheta2); 4842 mxFree(d2Bzdthetadrho); 4843 mxFree(d2Bzdrho2); 4844 4845 4846 if (flag_f0 == 1) {/*Wave aborption is calculated with a non-Maxwellian distribution function */ 4847 4848 mexPrintf("----------------------------------------\n"); 4849 mexPrintf("tol : %g\n",rayparam.tol[0]); 4850 mexPrintf("zZi(2) : %g\n",equilparam.zZi[1]); 4851 4852 mexPrintf("----------------------------------------\n"); 4853 mexPrintf("Wave aborption is calculated with a non-Maxwellian distribution function.\n"); 4854 mexPrintf("----------------------------------------\n"); 4855 mexPrintf("npn, pn(1),pn(end) : %d,%g,%g\n",distriparam.npn[0],distriparam.pn[0],distriparam.pn[distriparam.npn[0]-1]); 4856 mexPrintf("nmhu, mhu(1),mhu(end) : %d,%g,%g\n",distriparam.nmhu[0],distriparam.mhu[0],distriparam.mhu[distriparam.nmhu[0]-1]); 4857 mexPrintf("ne_ref, betath_ref : %g,%g\n",distriparam.ne_ref[0],distriparam.betath_ref[0]); 4858 4859 mexPrintf("----------------------------------------\n"); 4860 mexPrintf("f0_fit.coefs_f(1): %g\n",raydistri.f0_fit.coefs_f[0]); 4861 mexPrintf("f0_fit.coefs_dfdrho(1): %g\n",raydistri.f0_fit.coefs_dfdrho[0]); 4862 mexPrintf("f0_fit.coefs_d2fdrho2(1): %g\n",raydistri.f0_fit.coefs_d2fdrho2[0]); 4863 4864 mexPrintf("----------------------------------------\n"); 4865 4866 for (ip = 0; ip < distriparam.npn[0]; ip++) { 4867 if (distriparam.pn[ip] < 4.0) ip_ref = ip;/*seek for the index of the closest value of pn less than 4.0 */ 4868 } 4869 4870 for (jm = 0; jm < distriparam.nmhu[0]; jm++) { 4871 if (distriparam.mhu[jm] < 0.5) jm_ref = jm;/*seek for the index of the closest value of mhu less than 0.5 */ 4872 } 4873 4874 mexPrintf("ip_ref,pn(ip_ref): %d,%g\n",ip_ref,distriparam.pn[ip_ref]); 4875 mexPrintf("jm_ref,mhu(jm_ref): %d,%g\n",jm_ref,distriparam.mhu[jm_ref]); 4876 4877 f0_fit = mxCalloc(distriparam.npn[0]*distriparam.nmhu[0],sizeof(double)); 4878 df0drho_fit = mxCalloc(distriparam.npn[0]*distriparam.nmhu[0],sizeof(double)); 4879 d2f0drho2_fit = mxCalloc(distriparam.npn[0]*distriparam.nmhu[0],sizeof(double)); 4880 ppvald_1D(raydistri.f0_fit,rayparam.dS[0],0.25,f0_fit,df0drho_fit,d2f0drho2_fit); 4881 4882 mexPrintf("f0_fit(ip_ref,jm_ref,rho=0.25): %g\n",f0_fit[jm_ref*distriparam.npn[0]+ip_ref]); 4883 mxFree(f0_fit); 4884 mxFree(df0drho_fit); 4885 mxFree(d2f0drho2_fit); 4886 4887 mexPrintf("----------------------------------------\n"); 4888 mexPrintf("PSI_fit.nfourier: %g\n",raydistri.PSI_fit.dim_dbndrho[0]); 4889 mexPrintf("PSI_fit.coefs_bn(1): %g\n",raydistri.PSI_fit.coefs_bn[0]); 4890 mexPrintf("PSI_fit.coefs_dbndrho(1): %g\n",raydistri.PSI_fit.coefs_dbndrho[0]); 4891 4892 PSI_fit = mxCalloc(1,sizeof(double)); 4893 ppvald_2D(raydistri.PSI_fit,rayparam.dS[0],0.25,0.2,PSI_fit,&dummy1,&dummy1,&dummy1,&dummy1); 4894 mexPrintf("PSI(0.25,0.2) : %g\n",PSI_fit[0]); 4895 mxFree(PSI_fit); 4896 } 4897 4898 if (flag_fluct == 1) { 4899 4900 mexPrintf("----------------------------------------\n"); 4901 4902 halftanh(xm,&ht,&dht,&d2ht); 4903 mexPrintf("Fluctuations -> halftanh(x),x,f,df,d2f: %25.15g,%25.15g,%25.15g,%25.15g\n",xm,ht,dht,d2ht); 4904 halftanh(xp,&ht,&dht,&d2ht); 4905 mexPrintf("Fluctuations -> halftanh(x),x,f,df,d2f: %25.15g,%25.15g,%25.15g,%25.15g\n",xp,ht,dht,d2ht); 4906 4907 xq = mxCalloc(1,sizeof(double)); 4908 dxqdrho = mxCalloc(1,sizeof(double)); 4909 L_rho = mxCalloc(1,sizeof(double)); 4910 xL_theta = mxCalloc(1,sizeof(double)); 4911 dxL_thetadrho = mxCalloc(1,sizeof(double)); 4912 xL_perp = mxCalloc(1,sizeof(double)); 4913 dxL_perpdrho = mxCalloc(1,sizeof(double)); 4914 XL_phi = mxCalloc(1,sizeof(double)); 4915 dXL_phidrho = mxCalloc(1,sizeof(double)); 4916 dXL_phidtheta = mxCalloc(1,sizeof(double)); 4917 ppvald_0D(rayfluctuations.L_rho,L_rho); 4918 ppvald_1D(rayfluctuations.xq_fit,rayparam.dS[0],0.25,xq,dxqdrho,&dummy1); 4919 ppvald_1D(rayfluctuations.xL_theta_fit,rayparam.dS[0],0.25,xL_theta,dxL_thetadrho,&dummy1); 4920 ppvald_1D(rayfluctuations.xL_perp_fit,rayparam.dS[0],0.25,xL_perp,dxL_perpdrho,&dummy1); 4921 ppvald_2D(rayfluctuations.XL_phi_fit,rayparam.dS[0],0.25,0.2,XL_phi,dXL_phidrho,dXL_phidtheta,&dummy1,&dummy2); 4922 mexPrintf("----------------------------------------\n"); 4923 mexPrintf("Fluctuations -> xq(0.25),dxqdrho(0.25): %g,%g\n",xq[0],dxqdrho[0]); 4924 mexPrintf("Fluctuations -> L_rho: %g\n",L_rho[0]); 4925 mexPrintf("Fluctuations -> xL_theta(0.25),dxL_thetadrho(0.25): %g,%g\n",xL_theta[0],dxL_thetadrho[0]); 4926 mexPrintf("Fluctuations -> xL_perp(0.25),dxL_perpdrho(0.25): %g,%g\n",xL_perp[0],dxL_perpdrho[0]); 4927 mexPrintf("Fluctuations -> XL_phi(0.25,0.2),dXL_phidrho(0.25,0.2),dXL_phidtheta(0.25,0.2): %g,%g,%g\n",XL_phi[0],dXL_phidrho[0],dXL_phidtheta[0]); 4928 mexPrintf("----------------------------------------\n"); 4929 mxFree(xq); 4930 mxFree(dxqdrho); 4931 mxFree(L_rho); 4932 mxFree(xL_theta); 4933 mxFree(dxL_thetadrho); 4934 mxFree(xL_perp); 4935 mxFree(dxL_perpdrho); 4936 mxFree(XL_phi); 4937 mxFree(dXL_phidrho); 4938 mxFree(dXL_phidtheta); 4939 4940 if (fluctparam.ne_nmodel[0]) { 4941 mexPrintf("----------------------------------------\n"); 4942 mexPrintf("Fluctuations -> nmodel for ne: %d\n",fluctparam.ne_nmodel[0]); 4943 for (jf=0; jf < fluctparam.ne_nmodel[0]; jf++) { 4944 mexPrintf("--------------------------\n"); 4945 mexPrintf("Fluctuations for ne -> model(%d): %g\n",jf,fluctparam.ne_model[jf][0]); 4946 if (fluctparam.ne_sigmar_max[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_sigmar_max(%d): %g\n",0,fluctparam.ne_sigmar_max[jf][0]); 4947 if (fluctparam.ne_sigmar_hwhm[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_sigmar_hwhm(%d): %g\n",0,fluctparam.ne_sigmar_hwhm[jf][0]); 4948 if (fluctparam.ne_sigmar_rho[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_sigmar_rho(%d): %g\n",0,fluctparam.ne_sigmar_rho[jf][0]); 4949 if (fluctparam.ne_polmode[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_polmode(%d): %g\n",0,fluctparam.ne_polmode[jf][0]); 4950 if (fluctparam.ne_epsi_rho[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_epsi_rho(%d): %g\n",0,fluctparam.ne_epsi_rho[jf][0]); 4951 if (fluctparam.ne_epsi_theta[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_epsi_theta(%d): %g\n",0,fluctparam.ne_epsi_theta[jf][0]); 4952 if (fluctparam.ne_epsi_phi[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_epsi_phi(%d): %g\n",0,fluctparam.ne_epsi_phi[jf][0]); 4953 if (fluctparam.ne_lmin[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_lmin(%d): %g\n",0,fluctparam.ne_lmin[jf][0]); 4954 if (fluctparam.ne_mmin[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_mmin(%d): %g\n",0,fluctparam.ne_mmin[jf][0]); 4955 if (fluctparam.ne_nmin[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_nmin(%d): %g\n",0,fluctparam.ne_nmin[jf][0]); 4956 if (fluctparam.ne_lmax[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_lmax(%d): %g\n",0,fluctparam.ne_lmax[jf][0]); 4957 if (fluctparam.ne_mmax[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_mmax(%d): %g\n",0,fluctparam.ne_mmax[jf][0]); 4958 if (fluctparam.ne_nmax[jf] != NULL) mexPrintf("Fluctuations for ne -> ne_nmax(%d): %g\n",0,fluctparam.ne_nmax[jf][0]); 4959 if (fluctparam.ne_phase[jf] != NULL) mexPrintf("Fluctuations for ne -> phase(%d)(end): %g\n",jf,fluctparam.ne_phase[jf][fluctparam.ne_nphase[jf][0]-1]); 4960 4961 } 4962 } else { 4963 mexPrintf("Fluctuations -> no model for ne\n"); 4964 } 4965 4966 if (fluctparam.B_nmodel[0]) { 4967 mexPrintf("----------------------------------------\n"); 4968 mexPrintf("Fluctuations -> nmodel for B: %d\n",fluctparam.B_nmodel[0]); 4969 for (jf=0; jf < fluctparam.B_nmodel[0]; jf++) { 4970 mexPrintf("--------------------------\n"); 4971 mexPrintf("Fluctuations for B -> model(%d): %g\n",jf,fluctparam.B_model[jf][0]); 4972 if (fluctparam.B_sigmar_max[jf] != NULL) mexPrintf("Fluctuations for B -> B_sigmar_max(%d): %g\n",0,fluctparam.B_sigmar_max[jf][0]); 4973 if (fluctparam.B_sigmar_hwhm[jf] != NULL) mexPrintf("Fluctuations for B -> B_sigmar_hwhm(%d): %g\n",0,fluctparam.B_sigmar_hwhm[jf][0]); 4974 if (fluctparam.B_sigmar_rho[jf] != NULL) mexPrintf("Fluctuations for B -> B_sigmar_rho(%d): %g\n",0,fluctparam.B_sigmar_rho[jf][0]); 4975 if (fluctparam.B_polmode[jf] != NULL) mexPrintf("Fluctuations for B -> B_polmode(%d): %g\n",0,fluctparam.B_polmode[jf][0]); 4976 if (fluctparam.B_epsi_rho[jf] != NULL) mexPrintf("Fluctuations for B -> B_epsi_rho(%d): %g\n",0,fluctparam.B_epsi_rho[jf][0]); 4977 if (fluctparam.B_epsi_theta[jf] != NULL) mexPrintf("Fluctuations for B -> B_epsi_theta(%d): %g\n",0,fluctparam.B_epsi_theta[jf][0]); 4978 if (fluctparam.B_epsi_phi[jf] != NULL) mexPrintf("Fluctuations for B -> B_epsi_phi(%d): %g\n",0,fluctparam.B_epsi_phi[jf][0]); 4979 if (fluctparam.B_lmin[jf] != NULL) mexPrintf("Fluctuations for B -> B_lmin(%d): %g\n",0,fluctparam.B_lmin[jf][0]); 4980 if (fluctparam.B_mmin[jf] != NULL) mexPrintf("Fluctuations for B -> B_mmin(%d): %g\n",0,fluctparam.B_mmin[jf][0]); 4981 if (fluctparam.B_nmin[jf] != NULL) mexPrintf("Fluctuations for B -> B_nmin(%d): %g\n",0,fluctparam.B_nmin[jf][0]); 4982 if (fluctparam.B_lmax[jf] != NULL) mexPrintf("Fluctuations for B -> B_lmax(%d): %g\n",0,fluctparam.B_lmax[jf][0]); 4983 if (fluctparam.B_mmax[jf] != NULL) mexPrintf("Fluctuations for B -> B_mmax(%d): %g\n",0,fluctparam.B_mmax[jf][0]); 4984 if (fluctparam.B_nmax[jf] != NULL) mexPrintf("Fluctuations for B -> B_nmax(%d): %g\n",0,fluctparam.B_nmax[jf][0]); 4985 if (fluctparam.B_phase[jf] != NULL) mexPrintf("Fluctuations for B -> phase(%d)(end): %g\n",jf,fluctparam.B_phase[jf][fluctparam.B_nphase[jf][0]-1]); 4986 4987 if (rayfluctuations.B_sfx_fit[jf].dim_a0 != NULL) { 4988 mexPrintf("--------------------------\n"); 4989 sfx = mxCalloc(1,sizeof(double)); 4990 dsfxdrho = mxCalloc(1,sizeof(double)); 4991 dsfxdtheta = mxCalloc(1,sizeof(double)); 4992 ppvald_2D(rayfluctuations.B_sfx_fit[jf],rayparam.dS[0],0.25,0.2,sfx,dsfxdrho,dsfxdtheta,&dummy1,&dummy2,&dummy3); 4993 mexPrintf("B -> Xfx(0.25,0.2),dXfxdrho(0.25,0.2),dXfxdtheta(0.25,0.2): %g,%g,%g\n",sfx[0],dsfxdrho[0],dsfxdtheta[0]); 4994 mxFree(sfx); 4995 mxFree(dsfxdrho); 4996 mxFree(dsfxdtheta); 4997 } 4998 4999 if (rayfluctuations.B_sfy_fit[jf].dim_a0 != NULL) { 5000 sfy = mxCalloc(1,sizeof(double)); 5001 dsfydrho = mxCalloc(1,sizeof(double)); 5002 dsfydtheta = mxCalloc(1,sizeof(double)); 5003 ppvald_2D(rayfluctuations.B_sfy_fit[jf],rayparam.dS[0],0.25,0.2,sfy,dsfydrho,dsfydtheta,&dummy1,&dummy2,&dummy3); 5004 mexPrintf("B -> Xfy(0.25,0.2),dXfydrho(0.25,0.2),dXfydtheta(0.25,0.2): %g,%g,%g\n",sfy[0],dsfydrho[0],dsfydtheta[0]); 5005 mxFree(sfy); 5006 mxFree(dsfydrho); 5007 mxFree(dsfydtheta); 5008 } 5009 5010 if (rayfluctuations.B_sfz_fit[jf].dim_a0 != NULL) { 5011 sfz = mxCalloc(1,sizeof(double)); 5012 dsfzdrho = mxCalloc(1,sizeof(double)); 5013 dsfzdtheta = mxCalloc(1,sizeof(double)); 5014 ppvald_2D(rayfluctuations.B_sfz_fit[jf],rayparam.dS[0],0.25,0.2,sfz,dsfzdrho,dsfzdtheta,&dummy1,&dummy2,&dummy3); 5015 mexPrintf("B -> Xfz(0.25,0.2),dXfzdrho(0.25,0.2),dXfzdtheta(0.25,0.2): %g,%g,%g\n",sfz[0],dsfzdrho[0],dsfzdtheta[0]); 5016 mxFree(sfz); 5017 mxFree(dsfzdrho); 5018 mxFree(dsfzdtheta); 5019 } 5020 5021 } 5022 } else { 5023 mexPrintf("Fluctuations -> no model for B\n"); 5024 } 5025 } 5026 } else { 5027 if (rayparam.testmode[0]) {/* for tests if necessary */ 5028 5029 ytest[0] = 0.25; 5030 ytest[1] = 0.2; 5031 5032 interpequil_test(raymagnetic,rayprofiles,equilparam,ytest,flag); 5033 5034 mexPrintf("Bessel functions -> J0(0.5),J1(0.5),J2(0.5): %g,%g,%d\n",j0(0.5),j1(0.5),jn(2,0.5)); 5035 5036 mexPrintf("tol : %g\n",rayparam.tol[0]); 5037 5038 mexPrintf("zZi(1),zmi(1) : %g,%g\n",equilparam.zZi[0],equilparam.zmi[0]); 5039 mexPrintf("zZi(2),zmi(2) : %g,%g\n",equilparam.zZi[1],equilparam.zmi[1]); 5040 mexPrintf("ns : %d\n",equilparam.ns[0]); 5041 mexPrintf("Rp,ap,Zp,psia_apRp : %g,%g,%g,%g\n",equilparam.Rp[0],equilparam.ap[0],equilparam.Zp[0],equilparam.psia_apRp[0]); 5042 mexPrintf("--------------\n"); 5043 5044 if (equilparam.zZi[0] > 0) { 5045 mexPrintf("Te(0.25),dTedrho(0.25) (keV): %g,%g\n",rayprofiles.Te[0],rayprofiles.dTedY[0]); 5046 mexPrintf("ne(0.25),dnedrho(0.25) (10+19 m-3): %g,%g\n",rayprofiles.ne[0]/1e19,rayprofiles.dnedY[0]/1e19); 5047 mexPrintf("zTi(2,0.25),dzTidrho(2,0.25) (keV): %g,%g\n",rayprofiles.zTi[0],rayprofiles.dzTidY[0][0]); 5048 mexPrintf("zni(2,0.25),dznidrho(2,0.25) (10+19 m-3): %g,%g\n",rayprofiles.zni[0]/1e19,rayprofiles.dznidY[0][0]/1e19); 5049 } 5050 5051 mexPrintf("xn(0.25,0.2),dxndrho(0.25,0.2),dxndtheta(0.25,0.2) (m): %g,%g,%g\n",raymagnetic.xn[0],raymagnetic.dxndY[0],raymagnetic.dxndY[1]); 5052 mexPrintf("yn(0.25,0.2),dyndrho(0.25,0.2),dyndtheta(0.25,0.2) (m): %g,%g,%g\n",raymagnetic.yn[0],raymagnetic.dyndY[0],raymagnetic.dyndY[1]); 5053 mexPrintf("Bsn(0.25,0.2),dBsndrho(0.25,0.2),dBsndtheta(0.25,0.2) (T): %g,%g,%g\n",raymagnetic.Bsn[0],raymagnetic.dBsndY[0],raymagnetic.dBsndY[1]); 5054 mexPrintf("Bzn(0.25,0.2),dBzndrho(0.25,0.2),dBzndtheta(0.25,0.2) (T): %g,%g,%g\n",raymagnetic.Bzn[0],raymagnetic.dBzndY[0],raymagnetic.dBzndY[1]); 5055 mexPrintf("B(0.25,0.2),dBdrho(0.25,0.2),dBdtheta(0.25,0.2) (T): %g,%g,%g\n",raymagnetic.B[0],raymagnetic.dBdY[0],raymagnetic.dBdY[1]); 5056 mexPrintf("salpha(0.25,0.2),dsalphadrho(0.25,0.2),dsalphadtheta(0.25,0.2) (T): %g,%g,%g\n",raymagnetic.salpha[0],raymagnetic.dsalphadY[0],raymagnetic.dsalphadY[1]); 5057 mexPrintf("calpha(0.25,0.2),dcalphadrho(0.25,0.2),dcalphadtheta(0.25,0.2) (T): %g,%g,%g\n",raymagnetic.calpha[0],raymagnetic.dcalphadY[0],raymagnetic.dcalphadY[1]); 5058 mexPrintf("gradrhon(0.25,0.2),dgradrhondrho(0.25,0.2),dgradrhondtheta(0.25,0.2) (T): %g,%g,%g\n",raymagnetic.gradrhon[0],raymagnetic.dgradrhondY[0],raymagnetic.dgradrhondY[1]); 5059 5060 /*interpequil_test(raymagnetic,rayprofiles,equilparam,y0_in,flag); */ 5061 } 5062 5063 5064 } 5065 } 5066 5067 void halftanh(x,f,df,d2f) 5068 double x,*f,*df,*d2f; 5069 { 5070 if (x >= 0.0) { 5071 *f = x; 5072 *df = 1.0; 5073 *d2f = 0.0; 5074 } else { 5075 if (x < -400) { 5076 *f = -1; 5077 *df = 0; 5078 *d2f = 0; 5079 } else { 5080 *f = tanh(x); 5081 *df = 1.0/cosh(x)/cosh(x); 5082 *d2f = -2.0*df[0]*sinh(x)/cosh(x); 5083 } 5084 } 5085 } 5086 5087 /*Minizimation schemes giving out rho from (x0,y0) */ 5088 5089 void rho1D_dichotomy(rayequil_format rayequil,rayparam_format rayparam, equilparam_format equilparam, double *rho,double *theta,double *Y) 5090 { 5091 double down[2],up[2],res[2]; 5092 down[0]=0; 5093 up[0]=1; 5094 double dummy,x,y,dxdrho,dydrho; 5095 int k = 0; 5096 res[1]=1; 5097 int kmax = 60; 5098 double prec = 1e-10; 5099 while(k < kmax && fabs(res[1]) > prec) 5100 { 5101 k = k +1; 5102 5103 res[0] = (down[0] + up[0])/2; 5104 5105 ppvald_2D(rayequil.x_fit,rayparam.dS[0],down[0],theta[0],&x,&dxdrho,&dummy,&dummy,&dummy,&dummy); 5106 ppvald_2D(rayequil.y_fit,rayparam.dS[0],down[0],theta[0],&y,&dydrho,&dummy,&dummy,&dummy,&dummy); 5107 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5108 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5109 dxdrho=dxdrho/equilparam.ap[0];/*Mandatory normalization*/ 5110 dydrho=dydrho/equilparam.ap[0];/*Mandatory normalization*/ 5111 down[1] = dxdrho*(x-Y[0]) + dydrho*(y - Y[1]); 5112 5113 ppvald_2D(rayequil.x_fit,rayparam.dS[0],res[0],theta[0],&x,&dxdrho,&dummy,&dummy,&dummy,&dummy); 5114 ppvald_2D(rayequil.y_fit,rayparam.dS[0],res[0],theta[0],&y,&dydrho,&dummy,&dummy,&dummy,&dummy); 5115 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5116 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5117 dxdrho=dxdrho/equilparam.ap[0];/*Mandatory normalization*/ 5118 dydrho=dydrho/equilparam.ap[0];/*Mandatory normalization*/ 5119 res[1] = dxdrho*(x-Y[0]) + dydrho*(y - Y[1]); 5120 5121 if(down[1]*res[1]>0) 5122 { 5123 down[0]=res[0]; 5124 } 5125 else 5126 { 5127 up[0]=res[0]; 5128 } 5129 } 5130 rho[0]=res[0]; 5131 } 5132 5133 void rho1D_newton_numeric(rayequil_format rayequil,rayparam_format rayparam, equilparam_format equilparam, double *rho,double *theta,double *Y) 5134 { 5135 double down[2],res[2]; 5136 down[0]=0.05; 5137 res[0]=0.05000000000001; 5138 double dummy,x,y,dxdrho,dydrho; 5139 int k = 0; 5140 res[1]=1; 5141 int kmax = 10; 5142 double prec = 1e-10; 5143 double save1,save2; 5144 while(k < kmax && fabs(res[1]) > prec) 5145 { 5146 ppvald_2D(rayequil.x_fit,rayparam.dS[0],down[0],theta[0],&x,&dxdrho,&dummy,&dummy,&dummy,&dummy,&dummy); 5147 ppvald_2D(rayequil.y_fit,rayparam.dS[0],down[0],theta[0],&y,&dydrho,&dummy,&dummy,&dummy,&dummy,&dummy); 5148 5149 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5150 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5151 dxdrho=dxdrho/equilparam.ap[0];/*Mandatory normalization*/ 5152 dydrho=dydrho/equilparam.ap[0];/*Mandatory normalization*/ 5153 5154 down[1] = dxdrho*(x-Y[0]) + dydrho*(y - Y[1]); 5155 5156 ppvald_2D(rayequil.x_fit,rayparam.dS[0],res[0],theta[0],&x,&dxdrho,&dummy,&dummy,&dummy,&dummy,&dummy); 5157 ppvald_2D(rayequil.y_fit,rayparam.dS[0],res[0],theta[0],&y,&dydrho,&dummy,&dummy,&dummy,&dummy,&dummy); 5158 5159 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5160 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5161 dxdrho=dxdrho/equilparam.ap[0];/*Mandatory normalization*/ 5162 dydrho=dydrho/equilparam.ap[0];/*Mandatory normalization*/ 5163 5164 res[1] = dxdrho*(x-Y[0]) + dydrho*(y - Y[1]); 5165 5166 save1 = res[0]; 5167 save2 = res[1]; 5168 res[0] = res[0] - res[1]*((res[0] - down[0])/(res[1] - down[1])); 5169 down[0] = save1; 5170 down[1] = save2; 5171 5172 k = k +1; 5173 5174 } 5175 rho[0]=res[0]; 5176 } 5177 5178 void rho1D_newton_analytic(rayequil_format rayequil,rayparam_format rayparam, equilparam_format equilparam, double *rho,double *theta,double *Y) 5179 { 5180 double res[3]; 5181 5182 res[0]=0.05;/*res[0]=rho, res[1] = d(distance^2/2)/drho, res[2]= d2(distance^2/2)drho2*/ 5183 double dummy,x,y,dxdrho,dydrho,d2xdrho2,d2ydrho2; 5184 int k = 0; 5185 res[1]=1; 5186 int kmax = 10; 5187 double prec = 1e-9; 5188 while(k < kmax && fabs(res[1]) > prec) 5189 { 5190 ppvald_2D(rayequil.x_fit,rayparam.dS[0],res[0],theta[0],&x,&dxdrho,&dummy,&dummy,&dummy,&d2xdrho2); 5191 ppvald_2D(rayequil.y_fit,rayparam.dS[0],res[0],theta[0],&y,&dydrho,&dummy,&dummy,&dummy,&d2ydrho2); 5192 5193 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5194 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5195 dxdrho=dxdrho/equilparam.ap[0];/*Mandatory normalization*/ 5196 dydrho=dydrho/equilparam.ap[0];/*Mandatory normalization*/ 5197 d2xdrho2=d2xdrho2/equilparam.ap[0];/*Mandatory normalization*/ 5198 d2ydrho2=d2ydrho2/equilparam.ap[0];/*Mandatory normalization*/ 5199 5200 res[1] = dxdrho*(x-Y[0]) + dydrho*(y - Y[1]); 5201 5202 res[2] = d2xdrho2*(x-Y[0]) + d2ydrho2*(y - Y[1]) + pow(dxdrho,2) + pow(dydrho,2); 5203 5204 res[0] = res[0] - res[1]/res[2]; 5205 5206 k = k + 1; 5207 } 5208 rho[0]=res[0]; 5209 } 5210 5211 /*Minizimation schemes giving out rho and precise theta from (x0,y0) */ 5212 5213 void substitution_dichotomy_1D(rayequil_format rayequil,rayparam_format rayparam, equilparam_format equilparam, double *rho,double *theta,double *Y) 5214 { 5215 theta[0] = atan2(Y[1],Y[0]); 5216 rho1D_dichotomy(rayequil,rayparam,equilparam,rho,theta,Y); 5217 } 5218 5219 void substitution_dichotomy_2D(rayequil_format rayequil,rayparam_format rayparam, equilparam_format equilparam, double *rho,double *theta,double *Y) 5220 { 5221 theta[0] = atan2(Y[1],Y[0]); 5222 double down_t[2],up_t[2],res_t[2]; 5223 res_t[0] = theta[0]; 5224 down_t[0] = theta[0]*0.9; 5225 up_t[0] = theta[0]*1.1; 5226 double dummy,x,y,dxdtheta,dydtheta,rho_d,rho_m; 5227 int k=0; 5228 int kmax = 60; 5229 double prec = 1e-11; 5230 res_t[1] = 1; 5231 while(k < kmax && fabs(res_t[1]) > prec) 5232 { 5233 k = k + 1; 5234 res_t[0] = (down_t[0] + up_t[0])/2; 5235 rho1D_dichotomy(rayequil,rayparam,equilparam,&rho_d,&down_t[0],Y); 5236 rho1D_dichotomy(rayequil,rayparam,equilparam,&rho_m,&res_t[0],Y); 5237 5238 ppvald_2D(rayequil.x_fit,rayparam.dS[0],rho_d,down_t[0],&x,&dummy,&dxdtheta,&dummy,&dummy,&dummy); 5239 ppvald_2D(rayequil.y_fit,rayparam.dS[0],rho_d,down_t[0],&y,&dummy,&dydtheta,&dummy,&dummy,&dummy); 5240 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5241 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5242 dxdtheta=dxdtheta/equilparam.ap[0];/*Mandatory normalization*/ 5243 dydtheta=dydtheta/equilparam.ap[0];/*Mandatory normalization*/ 5244 down_t[1] = dxdtheta*(x-Y[0]) + dydtheta*(y-Y[1]); 5245 5246 ppvald_2D(rayequil.x_fit,rayparam.dS[0],rho_m,res_t[0],&x,&dummy,&dxdtheta,&dummy,&dummy,&dummy); 5247 ppvald_2D(rayequil.y_fit,rayparam.dS[0],rho_m,res_t[0],&y,&dummy,&dydtheta,&dummy,&dummy,&dummy); 5248 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5249 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5250 dxdtheta=dxdtheta/equilparam.ap[0];/*Mandatory normalization*/ 5251 dydtheta=dydtheta/equilparam.ap[0];/*Mandatory normalization*/ 5252 res_t[1] = dxdtheta*(x-Y[0]) + dydtheta*(y-Y[1]); 5253 5254 if(down_t[1]*res_t[1]>0) 5255 { 5256 down_t[0] = res_t[0]; 5257 } 5258 else 5259 { 5260 up_t[0] = res_t[0]; 5261 } 5262 } 5263 theta[0] = res_t[0]; 5264 rho1D_dichotomy(rayequil,rayparam,equilparam,rho,theta,Y); 5265 } 5266 5267 void substitution_newton_numeric_1D(rayequil_format rayequil,rayparam_format rayparam, equilparam_format equilparam, double *rho,double *theta,double *Y) 5268 { 5269 theta[0] = atan2(Y[1],Y[0]); 5270 rho1D_newton_numeric(rayequil,rayparam,equilparam,rho,theta,Y); 5271 5272 } 5273 5274 void substitution_newton_numeric_2D(rayequil_format rayequil,rayparam_format rayparam, equilparam_format equilparam, double *rho,double *theta,double *Y) 5275 { 5276 theta[0] = atan2(Y[1],Y[0]); 5277 double down_t[2],res_t[2]; 5278 double dummy,x,y,dxdtheta,dydtheta,rho_d,rho_m; 5279 down_t[0] = theta[0]; 5280 5281 rho1D_newton_numeric(rayequil,rayparam,equilparam,&rho_d,&down_t[0],Y); 5282 ppvald_2D(rayequil.x_fit,rayparam.dS[0],rho_d,down_t[0],&x,&dummy,&dxdtheta,&dummy,&dummy,&dummy,&dummy); 5283 ppvald_2D(rayequil.y_fit,rayparam.dS[0],rho_d,down_t[0],&y,&dummy,&dydtheta,&dummy,&dummy,&dummy,&dummy); 5284 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5285 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5286 dxdtheta=dxdtheta/equilparam.ap[0];/*Mandatory normalization*/ 5287 dydtheta=dydtheta/equilparam.ap[0];/*Mandatory normalization*/ 5288 down_t[1] = dxdtheta*(x-Y[0]) + dydtheta*(y-Y[1]); 5289 5290 res_t[0] = 1.0000000000001*down_t[0]; 5291 int kt=0; 5292 int ktmax = 10; 5293 double prec = 1e-11; 5294 res_t[1] = 1; 5295 double save1,save2; 5296 while(kt < ktmax && fabs(res_t[1]) > prec) 5297 { 5298 rho1D_newton_numeric(rayequil,rayparam,equilparam,&rho_m,&res_t[0],Y); 5299 ppvald_2D(rayequil.x_fit,rayparam.dS[0],rho_m,res_t[0],&x,&dummy,&dxdtheta,&dummy,&dummy,&dummy,&dummy); 5300 ppvald_2D(rayequil.y_fit,rayparam.dS[0],rho_m,res_t[0],&y,&dummy,&dydtheta,&dummy,&dummy,&dummy,&dummy); 5301 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5302 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5303 dxdtheta=dxdtheta/equilparam.ap[0];/*Mandatory normalization*/ 5304 dydtheta=dydtheta/equilparam.ap[0];/*Mandatory normalization*/ 5305 res_t[1] = dxdtheta*(x-Y[0]) + dydtheta*(y-Y[1]); 5306 5307 save1 = res_t[0]; 5308 save2 = res_t[1]; 5309 res_t[0] = res_t[0] - res_t[1]*((res_t[0] - down_t[0])/(res_t[1] - down_t[1])); 5310 down_t[0] = save1; 5311 down_t[1] = save2; 5312 5313 kt = kt + 1; 5314 5315 } 5316 theta[0] = res_t[0]; 5317 rho1D_newton_numeric(rayequil,rayparam,equilparam,rho,theta,Y); 5318 } 5319 5320 void substitution_newton_analytic_1D(rayequil_format rayequil,rayparam_format rayparam, equilparam_format equilparam, double *rho,double *theta,double *Y) 5321 { 5322 theta[0] = atan2(Y[1],Y[0]); 5323 rho1D_newton_analytic(rayequil,rayparam,equilparam,rho,theta,Y); 5324 } 5325 5326 void substitution_newton_analytic_2D(rayequil_format rayequil,rayparam_format rayparam, equilparam_format equilparam, double *rho,double *theta,double *Y) 5327 { 5328 theta[0] = atan2(Y[1],Y[0]); 5329 double res_t[3];/*res_t[0]=theta, res_t[1]=d(distance^2/2)dtheta, res_t[2]=d2(distance^2/2)dtheta2*/ 5330 res_t[0] = theta[0]; 5331 double dummy,x,y,dxdtheta,dydtheta,d2xdtheta2,d2ydtheta2,rho_s; 5332 int kt=0; 5333 int ktmax = 15; 5334 double prec = 1e-9; 5335 res_t[1] = 1; 5336 while(kt < ktmax && fabs(res_t[1]) > prec) 5337 { 5338 rho1D_newton_analytic(rayequil,rayparam,equilparam,&rho_s,&res_t[0],Y); 5339 5340 ppvald_2D(rayequil.x_fit,rayparam.dS[0],rho_s,res_t[0],&x,&dummy,&dxdtheta,&d2xdtheta2,&dummy,&dummy); 5341 ppvald_2D(rayequil.y_fit,rayparam.dS[0],rho_s,res_t[0],&y,&dummy,&dydtheta,&d2ydtheta2,&dummy,&dummy); 5342 5343 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5344 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5345 dxdtheta=dxdtheta/equilparam.ap[0];/*Mandatory normalization*/ 5346 dydtheta=dydtheta/equilparam.ap[0];/*Mandatory normalization*/ 5347 d2xdtheta2=d2xdtheta2/equilparam.ap[0];/*Mandatory normalization*/ 5348 d2ydtheta2=d2ydtheta2/equilparam.ap[0];/*Mandatory normalization*/ 5349 5350 res_t[1] = dxdtheta*(x-Y[0]) + dydtheta*(y-Y[1]); 5351 5352 res_t[2] = d2xdtheta2*(x-Y[0]) + d2ydtheta2*(y-Y[1]) + pow(dxdtheta,2) + pow(dydtheta,2); 5353 5354 res_t[0] = res_t[0] - res_t[1]/res_t[2]; 5355 5356 DUMP(res_t[0]); 5357 5358 kt = kt + 1; 5359 5360 } 5361 theta[0] = res_t[0]; 5362 rho1D_newton_analytic(rayequil,rayparam,equilparam,rho,theta,Y); 5363 } 5364 5365 void substitution_newton_mix_2D(rayequil_format rayequil,rayparam_format rayparam, equilparam_format equilparam, double *rho,double *theta,double *Y) 5366 { 5367 theta[0] = atan2(Y[1],Y[0]); 5368 double down_t[2],res_t[2]; 5369 down_t[0] = theta[0]; 5370 res_t[0] = 1.00000001*down_t[0]; 5371 double dummy,x,y,dxdtheta,dydtheta,rho_d,rho_m; 5372 int kt=0; 5373 int ktmax = 15; 5374 double prec = 1e-9; 5375 res_t[1] = 1; 5376 double save; 5377 5378 rho1D_newton_analytic(rayequil,rayparam,equilparam,&rho_d,&down_t[0],Y); 5379 5380 ppvald_2D(rayequil.x_fit,rayparam.dS[0],rho_d,down_t[0],&x,&dummy,&dxdtheta,&dummy,&dummy,&dummy); 5381 ppvald_2D(rayequil.y_fit,rayparam.dS[0],rho_d,down_t[0],&y,&dummy,&dydtheta,&dummy,&dummy,&dummy); 5382 5383 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5384 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5385 dxdtheta=dxdtheta/equilparam.ap[0];/*Mandatory normalization*/ 5386 dydtheta=dydtheta/equilparam.ap[0];/*Mandatory normalization*/ 5387 down_t[1] = dxdtheta*(x-Y[0]) + dydtheta*(y-Y[1]); 5388 5389 while(kt < ktmax && fabs(res_t[1]) > prec) 5390 { 5391 rho1D_newton_analytic(rayequil,rayparam,equilparam,&rho_m,&res_t[0],Y); 5392 5393 ppvald_2D(rayequil.x_fit,rayparam.dS[0],rho_m,res_t[0],&x,&dummy,&dxdtheta,&dummy,&dummy,&dummy); 5394 ppvald_2D(rayequil.y_fit,rayparam.dS[0],rho_m,res_t[0],&y,&dummy,&dydtheta,&dummy,&dummy,&dummy); 5395 x=x/equilparam.ap[0];/*Mandatory normalization*/ 5396 y=y/equilparam.ap[0];/*Mandatory normalization*/ 5397 dxdtheta=dxdtheta/equilparam.ap[0];/*Mandatory normalization*/ 5398 dydtheta=dydtheta/equilparam.ap[0];/*Mandatory normalization*/ 5399 5400 res_t[1] = dxdtheta*(x-Y[0]) + dydtheta*(y-Y[1]); 5401 5402 save = res_t[0]; 5403 res_t[0] = res_t[0] - res_t[1]*((res_t[0] - down_t[0])/(res_t[1] - down_t[1])); 5404 down_t[0] = save; 5405 down_t[1] = res_t[1]; 5406 5407 kt = kt + 1; 5408 5409 } 5410 theta[0] = res_t[0]; 5411 rho1D_newton_analytic(rayequil,rayparam,equilparam,rho,theta,Y); 5412 } 5413 5414 void substitution(rayequil_format rayequil,rayparam_format rayparam, equilparam_format equilparam, double *rho,double *theta,double *Y) 5415 { 5416 if((int)rayparam.substitution_method[0] == 1) 5417 { 5418 substitution_dichotomy_1D(rayequil,rayparam,equilparam,rho,theta,Y); 5419 } 5420 else 5421 { 5422 if((int)rayparam.substitution_method[0] == 2) 5423 { 5424 substitution_dichotomy_2D(rayequil,rayparam,equilparam,rho,theta,Y); 5425 } 5426 else 5427 { 5428 if((int)rayparam.substitution_method[0] == 3) 5429 { 5430 substitution_newton_numeric_1D(rayequil,rayparam,equilparam,rho,theta,Y); 5431 } 5432 else 5433 { 5434 if((int)rayparam.substitution_method[0] == 4) 5435 { 5436 substitution_newton_numeric_2D(rayequil,rayparam,equilparam,rho,theta,Y); 5437 } 5438 else 5439 { 5440 if((int)rayparam.substitution_method[0] == 4) 5441 { 5442 substitution_newton_numeric_2D(rayequil,rayparam,equilparam,rho,theta,Y); 5443 } 5444 else 5445 { 5446 if((int)rayparam.substitution_method[0] == 5) 5447 { 5448 substitution_newton_analytic_1D(rayequil,rayparam,equilparam,rho,theta,Y); 5449 } 5450 else 5451 { 5452 if((int)rayparam.substitution_method[0] == 6) 5453 { 5454 substitution_newton_analytic_2D(rayequil,rayparam,equilparam,rho,theta,Y); 5455 } 5456 else 5457 { 5458 substitution_newton_mix_2D(rayequil,rayparam,equilparam,rho,theta,Y); 5459 } 5460 } 5461 } 5462 } 5463 } 5464 } 5465 } 5466 } 5467 5468 void rhotheta2xy(rayparam_format rayparam, rayequil_format rayequil, equilparam_format equilparam, double *rho, double *theta, double *krho, double *m)/*Subfunction giving the cartesian from the curvilinear generalized vector, need to give each relevant components separately*/ 5469 { 5470 double *save; 5471 save = mxCalloc(4,sizeof(double));/*Saveguard of the relevant coordinates*/ 5472 save[0] = rho[0]; 5473 save[1] = theta[0]; 5474 save[2] = krho[0]; 5475 save[3] = m[0]; 5476 5477 double dfdrho,dfdtheta,d2fdtheta2,d2fdthetadrho,d2fdrho2; 5478 double gradrho,r,calpha,salpha; 5479 5480 ppvald_2D(rayequil.x_fit,rayparam.dS[0],save[0],save[1],rho,&dfdrho,&dfdtheta,&d2fdtheta2,&d2fdthetadrho,&d2fdrho2);/*Input x into the variable rho*/ 5481 ppvald_2D(rayequil.y_fit,rayparam.dS[0],save[0],save[1],theta,&dfdrho,&dfdtheta,&d2fdtheta2,&d2fdthetadrho,&d2fdrho2);/*Input y into the variable theta*/ 5482 5483 rho[0]=rho[0]/equilparam.ap[0];/*Normalization, rho stands for x*/ 5484 theta[0]=theta[0]/equilparam.ap[0];/*Normalization, theta stands for y*/ 5485 5486 ppvald_2D(rayequil.gradrho_fit,rayparam.dS[0],save[0],save[1],&gradrho,&dfdrho,&dfdtheta,&d2fdtheta2,&d2fdthetadrho,&d2fdrho2);/*Gives out gradrho*/ 5487 ppvald_2D(rayequil.r_fit,rayparam.dS[0],save[0],save[1],&r,&dfdrho,&dfdtheta,&d2fdtheta2,&d2fdthetadrho,&d2fdrho2);/*Gives out r*/ 5488 ppvald_2D(rayequil.calpha_fit,rayparam.dS[0],save[0],save[1],&calpha,&dfdrho,&dfdtheta,&d2fdtheta2,&d2fdthetadrho,&d2fdrho2);/*Gives out cos alpha*/ 5489 ppvald_2D(rayequil.salpha_fit,rayparam.dS[0],save[0],save[1],&salpha,&dfdrho,&dfdtheta,&d2fdtheta2,&d2fdthetadrho,&d2fdrho2);/*Gives out sin alpha*/ 5490 5491 r=r/equilparam.ap[0];/*Normalization*/ 5492 gradrho=gradrho*equilparam.ap[0];/*Normalization*/ 5493 5494 double cat = calpha*cos(save[1]) + salpha*sin(save[1]);/*Gives out cos(alpha - theta)*/ 5495 double sat = salpha*cos(save[1]) - sin(save[1])*calpha;/*Gives out sin(alpha - theta)*/ 5496 5497 krho[0] = gradrho*cat*save[2] -(sin(save[1])/r)*save[3];/*Input kx into the variable krho*/ 5498 m[0] = -gradrho*sat*save[2] + (cos(save[1])/r)*save[3];/*Input ky into the variable m*/ 5499 5500 mxFree(save); 5501 } 5502 5503 void xy2rhotheta(rayparam_format rayparam, rayequil_format rayequil, equilparam_format equilparam, double *x, double *y, double *kx, double *ky)/*Subfunction giving the curvilinear from the cartesian generalized vector, need to give each relevant components separately, here rho stand for x, theta for y, krho for kx and m for ky.*/ 5504 { 5505 double *save;/*Saveguard of the relevant coordinates*/ 5506 save = mxCalloc(4,sizeof(double)); 5507 save[0] = x[0]; 5508 save[1] = y[0]; 5509 save[2] = kx[0]; 5510 save[3] = ky[0]; 5511 5512 substitution(rayequil,rayparam,equilparam,x,y,save);/*Input rho and theta respectively in the variables x and y*/ 5513 5514 double dfdrho,dfdtheta,d2fdtheta2,d2fdthetadrho,d2fdrho2; 5515 double gradrho,r,calpha,salpha; 5516 5517 ppvald_2D(rayequil.gradrho_fit,rayparam.dS[0],x[0],y[0],&gradrho,&dfdrho,&dfdtheta,&d2fdtheta2,&d2fdthetadrho,&d2fdrho2);/*Gives out gradrho*/ 5518 ppvald_2D(rayequil.r_fit,rayparam.dS[0],x[0],y[0],&r,&dfdrho,&dfdtheta,&d2fdtheta2,&d2fdthetadrho,&d2fdrho2);/*Gives out r*/ 5519 ppvald_2D(rayequil.calpha_fit,rayparam.dS[0],x[0],y[0],&calpha,&dfdrho,&dfdtheta,&d2fdtheta2,&d2fdthetadrho,&d2fdrho2);/*Gives out cos alpha*/ 5520 ppvald_2D(rayequil.salpha_fit,rayparam.dS[0],x[0],y[0],&salpha,&dfdrho,&dfdtheta,&d2fdtheta2,&d2fdthetadrho,&d2fdrho2);/*Gives out sin alpha*/ 5521 5522 r=r/equilparam.ap[0];/*Normalization*/ 5523 gradrho=gradrho*equilparam.ap[0];/*Normalization*/ 5524 5525 double theta = y[0]; 5526 double cat = calpha*cos(theta) + salpha*sin(theta);/*Gives out cos(alpha - theta)*/ 5527 double sat = salpha*cos(theta) - sin(theta)*calpha;/*Gives out sin(alpha - theta)*/ 5528 5529 kx[0] = (1/(gradrho*calpha))*(cos(theta)*save[2] + sin(theta)*save[3]);/*Input krho into the variable kx*/ 5530 ky[0] = (r/calpha)*(sat*save[2] + cat*save[3]);/*Input m into the variable ky*/ 5531 5532 mxFree(save); 5533 }