00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "qcsteadystate.h"
00028 #include "qclinearalgebra.h"
00029
00030 QCSteadyState::QCSteadyState(void)
00031 {
00032 tolerance = 1e-10;
00033 }
00034
00035 QCSteadyState::~QCSteadyState(void)
00036 {
00037 F.free();
00038 }
00039
00040 void QCSteadyState::setConstant(QCComplexField<2>& field)
00041 {
00042 complexType tmp(1.0,0.0);
00043
00044 for(int k = 0; k < field.noOfColumns(); k ++)
00045 for(int j = 0; j < field.noOfRows(); j ++)
00046 field.assignElement(j,k,tmp);
00047 }
00048
00049 void QCSteadyState::usingTDGPFixedPoint(QCComplexField<2> &field, parameterType &deltaR, QCParameter &tdgpParameters)
00050 {
00051 parameterType sum = 0.0, oldSum = 1.0, r = 0.0;
00052
00053 parameterType smallOmegaSq = tdgpParameters.getParameter(0), mu = tdgpParameters.getParameter(1), g = tdgpParameters.getParameter(2);
00054 int radialExtent = field.noOfColumns()-1;
00055
00056
00057 F.free();
00058 F.resize(radialExtent+1);
00059 F = 1.0;
00060
00061
00062 while(abs(sum - oldSum) > tolerance && radialExtent > 0)
00063 {
00064 oldSum = sum;
00065 sum = 0.0;
00066 for(int j = 1; j < radialExtent; j ++)
00067 {
00068 r = j*deltaR;
00069 F(j) = 0.5*(F(j+1)+F(j-1)+0.5*deltaR*(F(j+1)-F(j-1))/j) - deltaR*deltaR*F(j)*(g*F(j)*F(j) + 0.5*smallOmegaSq*r*r - mu);
00070 sum += F(j);
00071 }
00072 F(radialExtent) = 0.0;
00073 F(0) = 2*F(1) - F(2);
00074 }
00075 completedSolution = TDGPFixedPt;
00076 }
00077
00078 void QCSteadyState::usingTDGPFixedPoint(QCComplexField<3> &field, parameterType &deltaR, QCParameter &tdgpParameters)
00079 {
00080 parameterType sum = 0.0, oldSum = 1.0, r = 0.0;
00081
00082 parameterType smallOmegaSq = tdgpParameters.getParameter(0), mu = tdgpParameters.getParameter(1), g = tdgpParameters.getParameter(2);
00083 int radialExtent = field.noOfColumns()-1;
00084
00085
00086 F.free();
00087 F.resize(radialExtent+1);
00088 F = 1.0;
00089
00090
00091 while(abs(sum - oldSum) > tolerance && radialExtent > 0)
00092 {
00093 oldSum = sum;
00094 sum = 0.0;
00095 for(int j = 1; j < radialExtent; j ++)
00096 {
00097 r = j*deltaR;
00098 F(j) = 0.5*(F(j+1)+F(j-1)+0.5*deltaR*(F(j+1)-F(j-1))/j) - deltaR*deltaR*F(j)*(g*F(j)*F(j) + 0.5*smallOmegaSq*r*r - mu);
00099 sum += F(j);
00100 }
00101 F(radialExtent) = 0.0;
00102 F(0) = 2*F(1) - F(2);
00103 }
00104 completedSolution = TDGPFixedPt;
00105 }
00106
00107 void QCSteadyState::usingTDGPVortexFixedPoint(QCComplexField<2> &field, parameterType &deltaR, QCParameter &tdgpParameters)
00108 {
00109 parameterType sum = 0.0, oldSum = 1.0, r = 0.0, frac1, frac2, internal, extra, jSq, jFrac;
00110
00111 parameterType smallOmegaSq = tdgpParameters.getParameter(0), mu = tdgpParameters.getParameter(1), g = tdgpParameters.getParameter(2), Omega = tdgpParameters.getParameter(5), n = tdgpParameters.getParameter(6);
00112 int radialExtent = field.noOfColumns()-1, count = 0;
00113
00114
00115 F.free();
00116 F.resizeAndPreserve(radialExtent+1);
00117 F = 1.0;
00118
00119 if(radialExtent > 0)
00120 F(0) = 0.0;
00121
00122
00123 while(abs(sum - oldSum) > tolerance && radialExtent > 0)
00124 {
00125 oldSum = sum;
00126 sum = 0.0;
00127 for(int j = 1; j < radialExtent; j ++)
00128 {
00129 r = j*deltaR;
00130 internal = g*F(j)*F(j) + 0.5*smallOmegaSq*r*r - mu + n*Omega;
00131 jFrac = (F(j+1)-F(j-1))/j;
00132 frac1 = 0.5*deltaR*jFrac;
00133 jSq = j*j;
00134 frac2 = (n*n)/(jSq)*F(j);
00135 extra = F(j+1)+F(j-1);
00136 F(j) = 0.5*(extra+frac1-frac2) - deltaR*deltaR*F(j)*(internal);
00137
00138
00139
00140 sum += F(j);
00141 }
00142
00143
00144
00145 F(radialExtent) = 0.0;
00146 }
00147 completedSolution = TDGPFixedPt;
00148 }
00149
00150 void QCSteadyState::usingTDGPVortexFixedPoint(QCComplexField<3> &field, parameterType xOffset, parameterType yOffset, parameterType zOffset, parameterType &deltaX, parameterType &deltaY, parameterType &deltaZ, parameterType &deltaR, QCParameter &tdgpParameters)
00151 {
00152 parameterType sum = 0.0, oldSum = 1.0, r = 0.0, x = 0.0, y = 0.0, z = 0.0;
00153
00154 parameterType smallOmegaSq = tdgpParameters.getParameter(0), mu = tdgpParameters.getParameter(1), g = tdgpParameters.getParameter(2), Omega = tdgpParameters.getParameter(5), n = tdgpParameters.getParameter(6);
00155 int radialExtent = field.noOfColumns()-1;
00156 parameterType m, rSquared;
00157 parameterType magnitude;
00158 int rInteger;
00159
00160
00161 F.free();
00162 F.resize(radialExtent+1);
00163 F = 1.0;
00164 if(radialExtent > 0)
00165 F(0) = 0.0;
00166
00167 for(int l = 0; l < field.height(); l ++)
00168 {
00169 z = l*deltaZ - zOffset;
00170
00171 while(abs(sum - oldSum) > tolerance && radialExtent > 0)
00172 {
00173 oldSum = sum;
00174 sum = 0.0;
00175 for(int j = 1; j < radialExtent; j ++)
00176 {
00177 r = j*deltaR;
00178 F(j) = 0.5*(F(j+1)+F(j-1)+0.5*deltaR*(F(j+1)-F(j-1))/j-(n*n)/(j*j)*F(j)) - deltaR*deltaR*F(j)*(g*F(j)*F(j) + 0.5*smallOmegaSq*(r*r + z*z) - mu + n*Omega);
00179 sum += F(j);
00180 }
00181 F(radialExtent) = 0.0;
00182 }
00183
00184 for(int k = 0; k < field.noOfColumns(); k++)
00185 {
00186 y = (k)*deltaY - yOffset;
00187 for(int j = 0; j < field.noOfRows(); j++)
00188 {
00189 x = (j)*deltaX - xOffset;
00190 rSquared = x*x + y*y;
00191 m = sqrt(rSquared)/deltaR;
00192 rInteger = int(m);
00193 magnitude = F(rInteger) + (m-rInteger)*( F(rInteger+1) - F(rInteger) );
00194 field.assignElement(j,k,l,magnitude);
00195 }
00196 }
00197 }
00198 }
00199
00200 void QCSteadyState::usingTDGPGaussSeidel(QCComplexField<2>& currentField, parameterType xOffset, parameterType yOffset, parameterType &h_x, parameterType &h_y, QCParameter &tdgpParameters)
00201 {
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 }
00226
00227 void QCSteadyState::usingTDGPFastSI(QCComplexField<2> &field, parameterType &h_r, QCParameter &tdgpParameters)
00228 {
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 }
00288
00289 void QCSteadyState::usingTDGPFastSI(QCComplexField<2>& currentField, parameterType xOffset, parameterType yOffset, parameterType &h_x, parameterType &h_y, QCParameter &tdgpParameters)
00290 {
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 }
00361
00362 void QCSteadyState::transferSolutionTo(QCComplexField<2> &field, parameterType xOffset, parameterType yOffset, parameterType &deltaX, parameterType &deltaY, parameterType &deltaR)
00363 {
00364 parameterType x, y;
00365 parameterType l, rSquared;
00366 parameterType magnitude;
00367 int rInteger;
00368
00369 if(completedSolution == TDGPFixedPt)
00370 {
00371 for(int k = 0; k < field.noOfColumns(); k++)
00372 {
00373 y = (k)*deltaY - yOffset;
00374 for(int j = 0; j < field.noOfRows(); j++)
00375 {
00376 x = (j)*deltaX - xOffset;
00377 rSquared = x*x + y*y;
00378 l = sqrt(rSquared)/deltaR;
00379 rInteger = int(l);
00380 magnitude = F(rInteger) + (l-rInteger)*( F(rInteger+1) - F(rInteger) );
00381 field.assignElement(j,k,magnitude);
00382 }
00383 }
00384 }
00385 else if(completedSolution == TDGPCartesian)
00386 {
00388 }
00389 }
00390
00391 void QCSteadyState::transferSolutionTo(QCComplexField<3> &field, parameterType xOffset, parameterType yOffset, parameterType zOffset, parameterType &deltaX, parameterType &deltaY, parameterType &deltaZ, parameterType &deltaR)
00392 {
00393 parameterType x, y, z;
00394 parameterType m, rSquared;
00395 parameterType magnitude;
00396 int rInteger;
00397
00398 if(completedSolution == TDGPFixedPt)
00399 {
00400 for(int l = 0; l < field.height(); l ++)
00401 {
00402 z = (l)*deltaZ - zOffset;
00403 for(int k = 0; k < field.noOfColumns(); k++)
00404 {
00405 y = (k)*deltaY - yOffset;
00406 for(int j = 0; j < field.noOfRows(); j++)
00407 {
00408 x = (j)*deltaX - xOffset;
00409 rSquared = x*x + y*y + z*z;
00410 m = sqrt(rSquared)/deltaR;
00411 rInteger = int(m);
00412 magnitude = F(rInteger) + (m-rInteger)*( F(rInteger+1) - F(rInteger) );
00413 field.assignElement(j,k,l,magnitude);
00414 }
00415 }
00416 }
00417 }
00418 else if(completedSolution == TDGPCartesian)
00419 {
00421 }
00422 }
00423
00424 bool QCSteadyState::output1DSolution(const char* fileName, parameterType &deltaR)
00425 {
00426 parameterType r;
00427 ofstream outFile(fileName,ios::out);
00428
00429 if(outFile.fail())
00430 {
00431 cerr << "File Error: " << fileName << endl;
00432 return false;
00433 }
00434 else
00435 {
00436
00437 for(int j = 0; j < F.extent(firstDim)/2; j++)
00438 {
00439 r = j*deltaR;
00440 outFile << r << "," << F(j) << endl;
00441 }
00442 outFile.close();
00443 return true;
00444 }
00445 }
00446
00447 void QCSteadyState::setBoundaryVanish(QCComplexField<2> &field)
00448 {
00449 int xExtent = field.noOfRows()-1, yExtent = field.noOfColumns()-1;
00450
00451
00452 for(int j = 1; j < xExtent; j ++)
00453 {
00454 field.assignElement(j,0,complexZero);
00455 field.assignElement(j,yExtent,complexZero);
00456 }
00457 for(int k = 0; k <= yExtent; k ++)
00458 {
00459 field.assignElement(0,k,complexZero);
00460 field.assignElement(xExtent,k,complexZero);
00461 }
00462 }
00463
00464 void QCSteadyState::setBoundaryFree(QCComplexField<2> &field)
00465 {
00466 int xExtent = field.noOfRows()-1, yExtent = field.noOfColumns()-1;
00467
00468 for(int k = 1; k < xExtent; k ++)
00469 {
00470 field.assignElement(k,0,2.0*field.retrieveElement(k,1) - field.retrieveElement(k,2));
00471 field.assignElement(k,yExtent,2.0*field.retrieveElement(k,yExtent-1) - field.retrieveElement(k,yExtent-2));
00472 }
00473 for(int l = 0; l <= yExtent; l ++)
00474 {
00475 field.assignElement(0,l,2.0*field.retrieveElement(1,l) - field.retrieveElement(2,l));
00476 field.assignElement(xExtent,l,2.0*field.retrieveElement(xExtent-1,l) - field.retrieveElement(xExtent-2,l));
00477 }
00478 field.assignElement(0,0,2.0*field.retrieveElement(1,1) - field.retrieveElement(2,2));
00479 field.assignElement(0,yExtent,2.0*field.retrieveElement(1,yExtent-1) - field.retrieveElement(2,yExtent-2));
00480 field.assignElement(xExtent,0,2.0*field.retrieveElement(xExtent-1,1) - field.retrieveElement(xExtent-2,2));
00481 field.assignElement(xExtent,yExtent,2.0*field.retrieveElement(xExtent-1,yExtent-1) - field.retrieveElement(xExtent-2,yExtent-2));
00482 }