00001
00002
00003
00004
00005 #include "cddefines.h"
00006 #include "dense.h"
00007 #include "trace.h"
00008 #include "thermal.h"
00009 #include "thirdparty.h"
00010 #include "phycon.h"
00011 #include "conv.h"
00012
00013
00014 static const int LOOPMAX = 35;
00015
00016
00017
00018 int ConvEdenIoniz(void)
00019 {
00020 long int LoopEden ,
00021
00022 LoopLimit ,
00023 LoopBig;
00024 bool lgFailLastTry;
00025 int kase = -1;
00026 static bool lgSlope_oscil=false;
00027
00028 static bool lgEden_ever_oscil = false;
00029 static double eden_assumed_old ,
00030 eden_assumed_minus_true_old,
00031 eden_assumed_minus_true,
00032 slope_ls=0., slope_ls_lastzone=0.;
00033 static bool lgEvalSlop_ls=0;
00034 double EdenEntry;
00035 static bool lgMustMalloc_temp_history = true;
00036 static double slope=-1.;
00037 double
00038
00039 EdenUpperLimit,
00040 EdenLowerLimit ,
00041 change_eden_rel2_tolerance ,
00042 PreviousChange;
00043
00044 DEBUG_ENTRY( "ConvEdenIoniz()" );
00045
00046
00047
00048
00049
00050 EdenEntry = dense.eden;
00051
00052 if( trace.lgTrace )
00053 {
00054 fprintf( ioQQQ, " \n" );
00055 fprintf( ioQQQ, " ConvEdenIoniz entered \n" );
00056 }
00057
00058 if( trace.nTrConvg>=3 )
00059 {
00060 fprintf( ioQQQ,
00061 " ConvEdenIoniz3 called, entering eden loop using solver %sw.\n",
00062 conv.chSolverEden);
00063 }
00064
00065
00066
00067 if( !conv.nTotalIoniz )
00068 {
00069
00070 conv.hist_temp_ntemp = -1;
00071 conv.hist_temp_nzone = -1;
00072
00073
00074
00075 }
00076
00077
00078 if( nzone!=conv.hist_temp_nzone )
00079 {
00080
00081 conv.hist_temp_nzone = nzone;
00082
00083
00084 conv.hist_temp_ntemp = 0;
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094 if( lgMustMalloc_temp_history )
00095 {
00096 lgMustMalloc_temp_history = false;
00097 conv.hist_temp_limit = 200;
00098 conv.hist_temp_temp = (double *)MALLOC( (size_t)((unsigned long)conv.hist_temp_limit*sizeof(double) ) );
00099 conv.hist_temp_heat = (double *)MALLOC( (size_t)((unsigned long)conv.hist_temp_limit*sizeof(double) ) );
00100 conv.hist_temp_cool = (double *)MALLOC( (size_t)((unsigned long)conv.hist_temp_limit*sizeof(double) ) );
00101 conv.chNotConverged = (char *)MALLOC( (size_t)((unsigned long)INPUT_LINE_LENGTH*sizeof(char) ) );
00102 conv.chConvEden = (char *)MALLOC( (size_t)((unsigned long)INPUT_LINE_LENGTH*sizeof(char) ) );
00103 conv.chConvIoniz = (char *)MALLOC( (size_t)((unsigned long)INPUT_LINE_LENGTH*sizeof(char) ) );
00104 strcpy( conv.chNotConverged, "none" );
00105 strcpy( conv.chConvEden, "none" );
00106 strcpy( conv.chConvIoniz, "none" );
00107 }
00108
00109 if( (conv.hist_temp_ntemp+1) >= conv.hist_temp_limit )
00110 {
00111 conv.hist_temp_limit *= 3;
00112 conv.hist_temp_temp = (double *)REALLOC( conv.hist_temp_temp, (size_t)((unsigned long)conv.hist_temp_limit*sizeof(double)));
00113 conv.hist_temp_heat = (double *)REALLOC( conv.hist_temp_heat, (size_t)((unsigned long)conv.hist_temp_limit*sizeof(double)));
00114 conv.hist_temp_cool = (double *)REALLOC( conv.hist_temp_cool, (size_t)((unsigned long)conv.hist_temp_limit*sizeof(double)));
00115 }
00116
00117
00118 conv.hist_temp_temp[conv.hist_temp_ntemp] = phycon.te;
00119 conv.hist_temp_heat[conv.hist_temp_ntemp] = thermal.htot;
00120 conv.hist_temp_cool[conv.hist_temp_ntemp] = thermal.ctot;
00121 ++conv.hist_temp_ntemp;
00122
00123 if( conv.nPres2Ioniz < 5 )
00124 lgEden_ever_oscil = false;
00125
00126
00127
00128 # define PRT_FAIL_LAST_TRY false
00129 lgFailLastTry = false;
00130 if( PRT_FAIL_LAST_TRY ) fprintf(ioQQQ,"lgFailLastTry set false\n");
00131
00132
00133
00134
00135 LoopBig = 0;
00136 while( LoopBig==0 || (lgFailLastTry && LoopBig==1 ) )
00137 {
00138
00139 if( strcmp( conv.chSolverEden , "simple" )== 0 )
00140 {
00141 static double damp;
00142 long int nLoopOscil;
00143 LoopEden = 0;
00144 conv.nConvIonizFails = 0;
00145
00146
00147
00148 LoopLimit = LOOPMAX;
00149
00150
00151 conv.lgEdenOscl = false;
00152 nLoopOscil = 0;
00153 # define PRT_EDEN_OSCIL false
00154 if( PRT_EDEN_OSCIL ) fprintf(ioQQQ," PRT_EDEN_OSCIIL setting lgEdenOscl FALSE2\n");
00155 lgFailLastTry = false;
00156 if( PRT_FAIL_LAST_TRY ) fprintf(ioQQQ,"lgFailLastTry set false\n");
00157
00158
00159 PreviousChange = 0.;
00160
00161 strcpy( conv.chConvIoniz, " NONE!!!!!" );
00162
00163
00164 eden_assumed_old = 0.;
00165 eden_assumed_minus_true_old = 0.;
00166
00167 damp = 1.;
00168
00169 if( !nzone )
00170 slope = 0.;
00171
00172
00173 do
00174 {
00175 double slopenew , slopeold;
00176
00177
00178 conv.lgConvEden = true;
00179
00180
00181 if( ConvIoniz() || lgAbort )
00182 {
00183 return 1;
00184 }
00185
00186
00187 eden_assumed_minus_true = dense.eden - dense.EdenTrue;
00188
00189 {
00190 static long int limEdenHistory=1000;
00191 static bool lgMustMalloc_eden_error_history = true;
00192 bool lgHistUpdate=false;
00193 static double *eden_error_history=NULL, *eden_assumed_history=NULL ,
00194 *stdarray;
00195 static long int nEval=-1 , nzoneUsed=-1, iterUsed=-1;
00196 if( lgMustMalloc_eden_error_history )
00197 {
00198 lgMustMalloc_eden_error_history = false;
00199 lgSlope_oscil = false;
00200 eden_error_history =
00201 (double*)MALLOC(sizeof(double)*(unsigned)limEdenHistory );
00202 eden_assumed_history =
00203 (double*)MALLOC(sizeof(double)*(unsigned)limEdenHistory );
00204 stdarray =
00205 (double*)MALLOC(sizeof(double)*(unsigned)limEdenHistory );
00206 }
00207 if( nzoneUsed!=nzone || iterUsed!=iteration )
00208 {
00209
00210 if( nzone==0 )
00211 {
00212 lgEvalSlop_ls = true;
00213 slope_ls = 1.;
00214 }
00215
00216 nEval = 0;
00217 nzoneUsed = nzone;
00218 iterUsed = iteration;
00219 lgSlope_oscil = false;
00220 slope_ls_lastzone = slope_ls;
00221 }
00222
00223 else if( !conv.lgSearch && !lgSlope_oscil )
00224 {
00225
00226 int ip = MAX2(0,nEval-1);
00227 if(
00228
00229 fabs(dense.eden - dense.EdenTrue)/dense.eden > conv.EdenErrorAllowed &&
00230
00231 (!nEval ||
00232
00233
00234 fabs((dense.eden - dense.EdenTrue)-eden_error_history[ip]*dense.gas_phase[ipHYDROGEN] )/dense.EdenTrue > 1e-5 ||
00235 fabs(dense.eden-eden_assumed_history[ip]*dense.gas_phase[ipHYDROGEN])/ dense.EdenTrue > 1e-5 ))
00236 {
00237
00238 eden_error_history[nEval] = (dense.eden - dense.EdenTrue)/dense.gas_phase[ipHYDROGEN];
00239 eden_assumed_history[nEval] = dense.eden/dense.gas_phase[ipHYDROGEN];
00240 stdarray[nEval] = 0.;
00241
00242
00243 if( eden_error_history[nEval] != 0. )
00244 {
00245 ++nEval;
00246 lgHistUpdate = true;
00247 }
00248
00249
00250
00251
00252
00253 }
00254 if( nEval>=limEdenHistory )
00255 {
00256
00257 limEdenHistory *=10;
00258 eden_error_history = (double *)REALLOC( eden_error_history, (unsigned)(limEdenHistory)*sizeof(double));
00259 eden_assumed_history = (double *)REALLOC( eden_error_history, (unsigned)(limEdenHistory)*sizeof(double));
00260 stdarray = (double *)REALLOC( eden_error_history, (unsigned)(limEdenHistory)*sizeof(double));
00261 }
00262 if( nEval>3 && lgHistUpdate )
00263 {
00264 double y_intercept, stdx, stdy, slope_save;
00265 slope_save = slope_ls;
00266
00267 if( linfit(nEval,
00268 eden_assumed_history,
00269 eden_error_history,
00270 y_intercept,
00271 stdy,
00272 slope_ls,
00273 stdx) )
00274 {
00275 int i;
00276 fprintf(ioQQQ," ConvEdenIoniz: linfit returns impossible condition, history follows:\n");
00277 fprintf(ioQQQ,"eden_error_history\tstdarray\n");
00278 for( i=0; i<nEval; ++i )
00279 {
00280 fprintf(ioQQQ,"%.3e\t%.4e\n",
00281 eden_error_history[i] ,
00282 stdarray[i] );
00283 }
00284 fprintf(ioQQQ,"\n");
00285 ShowMe();
00286 cdEXIT(EXIT_FAILURE);
00287 }
00288 lgEvalSlop_ls = true;
00289
00290 if( slope_ls*slope_save<0. )
00291 {
00292 slope_ls = slope_ls_lastzone;
00293 lgSlope_oscil = true;
00294 }
00295
00296
00297
00298
00299
00300
00301 }
00302 }
00303 }
00304 slopeold = slope;
00305
00306 slopenew = 0.;
00307 if( fabs(eden_assumed_minus_true_old) > 0. )
00308 {
00309 if( fabs( eden_assumed_old-dense.eden ) > SMALLFLOAT )
00310 {
00311 # define OLDFAC 0.75
00312 slopenew = (eden_assumed_minus_true_old - eden_assumed_minus_true) / (eden_assumed_old-dense.eden );
00313
00314 # if 0
00315 if( slope !=0. && slope*slopenew>=0.)
00316 slope = OLDFAC*slope + (1.-OLDFAC)*slopenew;
00317 else if( slope==0.)
00318 slope = slopenew;
00319 # endif
00320 if( slope !=0. )
00321 slope = OLDFAC*slope + (1.-OLDFAC)*slopenew;
00322 else
00323 slope = slopenew;
00324 # undef OLDFAC
00325 }
00326
00327
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 if( fabs(dense.eden-dense.EdenTrue)/SDIV(dense.eden) >=
00340 conv.EdenErrorAllowed )
00341 {
00342 double eden_proposed;
00343
00344
00345 conv.lgConvEden = false;
00346 strcpy( conv.chConvIoniz, "Ne big chg" );
00347
00348
00349 ASSERT( dense.eden > SMALLFLOAT );
00350
00351
00352
00353
00354 if( conv.lgSearch && dense.EdenTrue > SMALLFLOAT )
00355 {
00356 dense.eden = pow(10.,
00357 (log10(dense.eden) + log10(dense.EdenTrue))/ 2.);
00358 }
00359 else
00360 {
00361
00362
00363
00364
00365
00366
00367
00368 if( 0 && dense.eden_from_metals > 0.5 )
00369 {
00370 static long int nzone_eval=-1;
00371 static bool lgOscilkase10 = false;
00372
00373
00374
00375 # define KASE_EDEN_NOT_ION 10
00376 if( nzone != nzone_eval )
00377 {
00378 nzone_eval = nzone;
00379 lgOscilkase10 = false;
00380 }
00381
00382
00383 if( PreviousChange*(dense.EdenTrue-dense.eden) < 0. && nzone_eval > 6 )
00384 lgOscilkase10 = true;
00385
00386
00387
00388 change_eden_rel2_tolerance = 0.2;
00389 if( lgOscilkase10 )
00390 {
00391
00392 change_eden_rel2_tolerance = 0.05;
00393 }
00394 kase = KASE_EDEN_NOT_ION;
00395 }
00396
00397
00398
00399
00400
00401 else if( PreviousChange*(dense.EdenTrue-dense.eden) < 0. )
00402 {
00403
00404 conv.lgEdenOscl = true;
00405 nLoopOscil = LoopEden;
00406
00407
00408 damp = MAX2( 0.05, damp * 0.75 );
00409 if( PRT_EDEN_OSCIL )
00410 fprintf(ioQQQ," PRT_EDEN_OSCIIL setting lgEdenOscl true, previous change %e new change %e\n",
00411 PreviousChange,dense.EdenTrue-dense.eden);
00412
00413
00414
00415
00416 change_eden_rel2_tolerance = 0.5;
00417
00418 change_eden_rel2_tolerance = 0.25;
00419 kase = 0;
00420 }
00421 else if( lgFailLastTry )
00422 {
00423
00424
00425 change_eden_rel2_tolerance = 0.5;
00426 kase = 1;
00427 }
00428
00429
00430 else if( LoopEden > 4 && !lgEden_ever_oscil &&
00431 fabs( (dense.EdenTrue-dense.eden)/dense.eden) > 3.*conv.EdenErrorAllowed )
00432 {
00433
00434
00435
00436 change_eden_rel2_tolerance = 3.;
00437 kase = 2;
00438 }
00439 else if( conv.lgEdenOscl )
00440 {
00441
00442
00443 change_eden_rel2_tolerance = 0.25;
00444 kase = 4;
00445 }
00446 else
00447 {
00448
00449
00450
00451
00452 change_eden_rel2_tolerance = 1.;
00453 kase = 3;
00454 }
00455
00456
00457 PreviousChange = dense.EdenTrue - dense.eden;
00458
00459
00460 eden_assumed_minus_true_old = eden_assumed_minus_true;
00461
00462
00463 eden_assumed_old = dense.eden;
00464
00465
00466
00467 EdenUpperLimit = dense.eden * (1. + damp*conv.EdenErrorAllowed*change_eden_rel2_tolerance);
00468 EdenLowerLimit = dense.eden / (1. + damp*conv.EdenErrorAllowed*change_eden_rel2_tolerance);
00469
00470 # define USE_NEW true
00471 # define PRT_NEW false
00472 if( PRT_NEW && USE_NEW )
00473 fprintf(ioQQQ,"DEBUG slope\t%li\t%li\t%.3f\t%.3f\t%.3f\t%.4e\t%.4e\t%.4f\t%.3f\t%.3e\n",
00474 nzone,
00475 conv.nPres2Ioniz,
00476 slope ,
00477 slopeold ,
00478 slopenew ,
00479 dense.eden,
00480 dense.EdenTrue,
00481 (dense.eden-dense.EdenTrue)/SDIV(dense.eden) ,
00482 change_eden_rel2_tolerance ,
00483 EdenLowerLimit);
00484 if( lgEvalSlop_ls )
00485 slope = slope_ls;
00486 if( USE_NEW && slope !=0. )
00487 {
00488
00489
00490 eden_proposed = dense.eden + (dense.EdenTrue - dense.eden)/slope_ls * damp;
00491 }
00492 else
00493 {
00494 eden_proposed = dense.EdenTrue;
00495 }
00496 # if 0
00497 {
00498 #include "grainvar.h"
00499 fprintf(ioQQQ,"DEBUG eden grn\t%e\t%e\t%e\t%e\n",
00500 dense.eden, eden_proposed,dense.EdenTrue, -gv.TotalEden);
00501 }
00502 # endif
00503
00504
00505
00506
00507 if( eden_proposed > EdenUpperLimit )
00508 {
00509
00510 dense.eden = EdenUpperLimit;
00511 }
00512
00513 else if( eden_proposed < EdenLowerLimit )
00514 {
00515
00516 dense.eden = EdenLowerLimit;
00517 }
00518 else
00519 {
00520
00521
00522 dense.eden = eden_proposed;
00523 }
00524
00525 if( trace.lgTrace && trace.lgNeBug )
00526 {
00527 fprintf( ioQQQ,
00528 " ConvEdenIoniz, chg ne to %.3e eden_assumed_old%10.3e ratio%10.3e EdenTrue=%10.3e\n",
00529 dense.eden, eden_assumed_old, dense.eden/eden_assumed_old, dense.EdenTrue );
00530 }
00531 }
00532
00533 }
00534
00535
00536
00537 else
00538 {
00539
00540
00541 if( fabs(dense.eden-dense.EdenTrue)/dense.EdenTrue > conv.EdenErrorAllowed/10. &&
00542
00543
00544 kase !=KASE_EDEN_NOT_ION )
00545 {
00546
00547
00548
00549
00550
00551 dense.eden = dense.eden + (dense.EdenTrue-dense.eden)/MAX2(1.,slope_ls)*damp;
00552
00553 if( trace.nTrConvg>=3 )
00554 {
00555 fprintf( ioQQQ,
00556 " ConvEdenIoniz3 converged eden, re-calling ConvIoniz with EdenTrue=%.4e (was %.4e).\n",
00557 dense.EdenTrue ,
00558 dense.eden );
00559 }
00560
00561
00562
00563
00564
00565
00566 if( ConvIoniz() )
00567 {
00568 return 1;
00569 }
00570 }
00571 else if( trace.nTrConvg>=3 )
00572 {
00573 fprintf( ioQQQ,
00574 " ConvEdenIoniz3 no need to re-call ConvIoniz since eden did not change much.\n");
00575 }
00576
00577
00578
00579
00580
00581 if(
00582 fabs(dense.eden-dense.EdenTrue)/SDIV(dense.eden) >=
00583 conv.EdenErrorAllowed )
00584 {
00585
00586
00587 conv.lgConvEden = false;
00588
00589
00590
00591 lgFailLastTry = true;
00592 if( PRT_FAIL_LAST_TRY ) fprintf(ioQQQ,"lgFailLastTry set true\n");
00593
00594 lgEden_ever_oscil = true;
00595 }
00596 }
00597 {
00598
00599
00600 enum {DEBUG_LOC=false};
00601
00602 if( DEBUG_LOC )
00603 {
00604 fprintf(ioQQQ,"edendebugg %li\t%.2e\t%.2e\t%.2e\t%.2e\n",
00605 nzone,dense.eden ,eden_assumed_old, (dense.eden-eden_assumed_old)/dense.eden, dense.EdenTrue);
00606 }
00607 }
00608 if( trace.lgTrace && trace.lgNeBug )
00609 {
00610 fprintf( ioQQQ,
00611 " ConvEdenIoniz, chg ne to%10.3e eden_assumed_old%10.3e ratio%10.3e EdenTrue=%10.3e converge=%c\n",
00612 dense.eden, eden_assumed_old, dense.eden/SDIV(eden_assumed_old), dense.EdenTrue ,TorF( conv.lgConvEden));
00613 }
00614
00615 if( trace.nTrConvg>=3 )
00616 {
00617
00618 fprintf( ioQQQ, " ConvEdenIoniz3 loop:%4ld ",
00619 LoopEden );
00620
00621
00622 if( conv.lgConvEden )
00623 {
00624 fprintf( ioQQQ, " converged, eden rel error:%g ",
00625 (dense.EdenTrue-dense.eden)/dense.EdenTrue );
00626 }
00627 else if( eden_assumed_old > SMALLFLOAT )
00628 {
00629
00630 fprintf( ioQQQ, " NOT Converged! corr:%8.4f prop:%9.5f ",
00631 (dense.EdenTrue-eden_assumed_old)/eden_assumed_old ,
00632 (dense.eden-eden_assumed_old)/eden_assumed_old );
00633 }
00634
00635 fprintf( ioQQQ, " new ne:%.6e true:%.6e kase:%i slope:%.3e osc:%c",
00636 dense.eden ,
00637 dense.EdenTrue ,
00638 kase ,
00639 slope_ls,
00640 TorF(lgSlope_oscil));
00641
00642 if( conv.lgEdenOscl )
00643 {
00644 fprintf( ioQQQ, " EDEN OSCIL1 damp %.4f\n", damp);
00645 }
00646 else
00647 {
00648 fprintf( ioQQQ, "\n");
00649 }
00650 }
00651
00652
00653 ++LoopEden;
00654
00655
00656
00657
00658 if( LoopEden - nLoopOscil >4 && fabs(slope_ls) < 3. )
00659 {
00660 conv.lgEdenOscl = false;
00661
00662 damp = 1.;
00663 }
00664
00665
00666
00667
00668 if( LoopEden == (LOOPMAX-1) && !conv.lgEdenOscl && conv.nConvIonizFails==0)
00669
00670
00671 LoopLimit *= 4;
00672
00673 } while( !conv.lgConvEden && LoopEden < LoopLimit && !lgAbort );
00674 }
00675
00676 else if( strcmp( conv.chSolverEden , "new" )== 0 )
00677 {
00678
00679 double PreviousEdenError = 0.;
00680 double CurrentEdenError = 0.;
00681 double CurrentEden = 0.;
00682 double ProposedEden,
00683 FractionChangeEden = 0.;
00684
00685
00686 LoopEden = 0;
00687 conv.nConvIonizFails = 0;
00688
00689
00690 LoopLimit = LOOPMAX;
00691
00692
00693 conv.lgEdenOscl = false;
00694 if( PRT_EDEN_OSCIL ) fprintf(ioQQQ," PRT_EDEN_OSCIIL setting lgEdenOscl FALSE1\n");
00695
00696
00697
00698 change_eden_rel2_tolerance = 0.02;
00699
00700 strcpy( conv.chConvIoniz, " NONE!!!!!" );
00701
00702
00703
00704 do
00705 {
00706
00707
00708
00709 conv.lgConvEden = true;
00710
00711 if( trace.nTrConvg>=3 )
00712 fprintf( ioQQQ, " ConvEdenIoniz3 calling ConvIoniz with eden= %.4e\n",dense.eden);
00713
00714
00715 if( ConvIoniz() )
00716 {
00717 return 1;
00718 }
00719
00720
00721
00722
00723
00724
00725
00726
00727 CurrentEden = dense.eden;
00728
00729
00730 CurrentEdenError = dense.EdenTrue - dense.eden;
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742 if(
00743 (LoopEden==0 && fabs(CurrentEdenError)/dense.EdenTrue <= conv.EdenErrorAllowed/2.) ||
00744 (LoopEden>0 && fabs(CurrentEdenError)/dense.EdenTrue <= conv.EdenErrorAllowed
00745 && FractionChangeEden < conv.EdenErrorAllowed / 2.) )
00746 break;
00747
00748
00749
00750 conv.lgConvEden = false;
00751 strcpy( conv.chConvIoniz, "Ne big chg" );
00752
00753
00754 if( conv.lgSearch )
00755 {
00756 dense.eden = pow(10.,
00757 (log10(dense.eden) + log10(dense.EdenTrue))/ 2.);
00758 }
00759 else
00760 {
00761
00762
00763
00764 if( PreviousEdenError*CurrentEdenError < 0. )
00765 {
00766
00767
00768 slope = (PreviousEdenError - CurrentEdenError ) /
00769 ( eden_assumed_old - CurrentEden );
00770
00771 ProposedEden = eden_assumed_old - PreviousEdenError / slope;
00772
00773
00774 ASSERT( ProposedEden >= MIN2( eden_assumed_old , CurrentEden ) );
00775 ASSERT( ProposedEden <= MAX2( eden_assumed_old , CurrentEden ) );
00776
00777 change_eden_rel2_tolerance *= 0.25;
00778 if( trace.nTrConvg>=3 )
00779 fprintf( ioQQQ,
00780 " ConvEdenIoniz3 bracketed electron density factor now %.3e error is %.4f proposed ne %.4e\n",
00781 change_eden_rel2_tolerance,
00782 (dense.EdenTrue-dense.eden)/dense.EdenTrue, ProposedEden);
00783 }
00784 else
00785 {
00786
00787
00788
00789 EdenUpperLimit = dense.eden * (1. + change_eden_rel2_tolerance);
00790 EdenLowerLimit = dense.eden / (1. + change_eden_rel2_tolerance);
00791
00792
00793 if( dense.EdenTrue > EdenUpperLimit )
00794 {
00795
00796 ProposedEden = EdenUpperLimit;
00797 }
00798 else if( dense.EdenTrue < EdenLowerLimit )
00799 {
00800
00801 ProposedEden = EdenLowerLimit;
00802 }
00803 else
00804 {
00805
00806 ProposedEden = dense.EdenTrue;
00807 }
00808 if( trace.nTrConvg>=3 )
00809 fprintf( ioQQQ,
00810 " ConvEdenIoniz3 elec dens fac %.3e err is %.4f prop ne %.4e cor ne %.4e slope=%.2e\n",
00811 change_eden_rel2_tolerance,
00812 (dense.EdenTrue-dense.eden)/dense.EdenTrue ,
00813 ProposedEden,
00814 dense.EdenTrue,slope);
00815 }
00816
00817
00818 PreviousEdenError = CurrentEdenError;
00819 eden_assumed_old = CurrentEden;
00820 FractionChangeEden = fabs( dense.eden - ProposedEden ) / dense.EdenTrue;
00821 dense.eden = ProposedEden;
00822
00823 if( trace.lgTrace && trace.lgNeBug )
00824 {
00825 fprintf( ioQQQ,
00826 " ConvEdenIoniz, chg ne to%10.3e eden_assumed_old%10.3e ratio%10.3e EdenTrue=%10.3e\n",
00827 dense.eden, eden_assumed_old, dense.eden/eden_assumed_old, dense.EdenTrue );
00828 }
00829 }
00830
00831 ++LoopEden;
00832 } while( LoopEden < LoopLimit && !lgAbort );
00833
00834
00835
00836
00837
00838 if( trace.nTrConvg>=3 )
00839 fprintf( ioQQQ,
00840 " ConvEdenIoniz3 converged eden, current error is %.4f, calling ConvIoniz with final density=EdenTrue=%.4e\n",
00841 (dense.EdenTrue - dense.eden)/dense.EdenTrue,dense.EdenTrue);
00842 dense.eden = dense.EdenTrue;
00843
00844
00845 if( ConvIoniz() )
00846 {
00847 if( trace.nTrConvg>=3 )
00848 fprintf( ioQQQ,
00849 " ConvEdenIoniz3 eden no longer converged eden, current error is %.4f\n",
00850 (dense.EdenTrue - dense.eden)/dense.EdenTrue);
00851 }
00852
00853
00854
00855 if(
00856 fabs(dense.eden-dense.EdenTrue)/dense.EdenTrue >
00857 conv.EdenErrorAllowed )
00858 {
00859
00860
00861 conv.lgConvEden = false;
00862 if( trace.nTrConvg>=3 )
00863 fprintf( ioQQQ,
00864 " ConvEdenIoniz3 setting eden not converged, error %.4f, exiting\n",
00865 (dense.eden-dense.EdenTrue)/dense.EdenTrue );
00866 }
00867 else
00868 {
00869 conv.lgConvEden = true;
00870 }
00871
00872 if( trace.lgTrace && trace.lgNeBug )
00873 {
00874 fprintf( ioQQQ,
00875 " ConvEdenIoniz, chg ne to%10.3e eden_assumed_old%10.3e ratio%10.3e EdenTrue=%10.3e converge=%c\n",
00876 dense.eden, eden_assumed_old, dense.eden/eden_assumed_old, dense.EdenTrue ,TorF( conv.lgConvEden));
00877 }
00878
00879 if( trace.nTrConvg>=3 )
00880 {
00881 fprintf( ioQQQ, " ConvEdenIoniz3 %4ld new ne=%12.4e true=%12.4e",
00882 LoopEden, dense.eden , dense.EdenTrue );
00883
00884
00885 if( conv.lgConvEden )
00886 {
00887 fprintf( ioQQQ, " converged, eden rel error is %g ",
00888 (dense.EdenTrue-dense.eden)/dense.EdenTrue );
00889 }
00890 else
00891 {
00892 fprintf( ioQQQ, " NOCONV corr:%7.3f prop:%7.3f ",
00893 (dense.EdenTrue-eden_assumed_old)/eden_assumed_old ,
00894 (dense.eden-eden_assumed_old)/eden_assumed_old );
00895 }
00896 if( conv.lgEdenOscl )
00897 fprintf( ioQQQ, " EDEN OSCIL2 \n");
00898 }
00899
00900 }
00901 else
00902 {
00903 fprintf( ioQQQ, "ConvEdenIoniz finds insane solver %s \n" , conv.chSolverEden );
00904 ShowMe();
00905 }
00906 ++LoopBig;
00907 }
00908
00909 if( trace.nTrConvg>=3 )
00910 {
00911 fprintf( ioQQQ, " ConvEdenIoniz3 exits, lgConvEden=%1c entry eden %.4e -> %.4e rel change %.3f\n" ,
00912 TorF(conv.lgConvEden ),
00913 EdenEntry ,
00914 dense.eden ,
00915 (EdenEntry-dense.eden)/SDIV( dense.eden ) );
00916 }
00917 else if( trace.lgTrace )
00918 {
00919 fprintf( ioQQQ, " ConvEdenIoniz exits zn %.2f lgConvEden=%1c entry eden %.4e -> %.4e rel change %.3f\n" ,
00920 fnzone,
00921 TorF(conv.lgConvEden ),
00922 EdenEntry ,
00923 dense.eden ,
00924 (EdenEntry-dense.eden)/SDIV( dense.eden ) );
00925 }
00926
00927 return 0;
00928 }
00929
00930
00931 bool lgConvEden(void)
00932 {
00933 bool lgRet;
00934
00935
00936 if( fabs(dense.eden-dense.EdenTrue)/SDIV(dense.eden) >=
00937 conv.EdenErrorAllowed )
00938 {
00939 lgRet = false;
00940 conv.lgConvEden = false;
00941 }
00942 else
00943 {
00944 lgRet = true;
00945 conv.lgConvEden = true;
00946 }
00947 return lgRet;
00948 }