00001
00002
00003
00004
00005
00006 #include "cddefines.h"
00007 #include "dynamics.h"
00008 #include "trace.h"
00009 #include "elementnames.h"
00010 #include "punch.h"
00011 #include "phycon.h"
00012 #include "secondaries.h"
00013 #include "stopcalc.h"
00014 #include "grainvar.h"
00015 #include "highen.h"
00016 #include "dense.h"
00017 #include "hmi.h"
00018 #include "rfield.h"
00019 #include "pressure.h"
00020 #include "taulines.h"
00021 #include "rt.h"
00022 #include "grains.h"
00023 #include "atmdat.h"
00024 #include "ionbal.h"
00025 #include "opacity.h"
00026 #include "cooling.h"
00027 #include "thermal.h"
00028 #include "mole.h"
00029 #include "iso.h"
00030 #include "conv.h"
00031
00032
00033
00034 STATIC bool lgIonizConverg(
00035
00036 long int nelem ,
00037
00038 double delta ,
00039
00040 bool lgPrint )
00041 {
00042 bool lgConverg_v;
00043 long int ion;
00044 double Abund,
00045 bigchange ,
00046 change ,
00047 one;
00048 double abundold=0. , abundnew=0.;
00049
00050
00051 static realnum OldFracs[LIMELM+1][LIMELM+1];
00052
00053 if( !dense.lgElmtOn[nelem] )
00054 return true;
00055
00056 DEBUG_ENTRY( "lgIonizConverg()" );
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 if( conv.nPres2Ioniz )
00069 {
00070
00071
00072 bigchange = 0.;
00073 change = 0.;
00074 Abund = dense.gas_phase[nelem];
00075
00076
00077
00078 for( ion=0; ion <= (nelem+1); ++ion )
00079 {
00080
00081 if( OldFracs[nelem][ion]/Abund > 1e-4 &&
00082 dense.xIonDense[nelem][ion]/Abund > 1e-4 )
00083
00084 {
00085
00086 one = fabs(dense.xIonDense[nelem][ion]-OldFracs[nelem][ion])/
00087 OldFracs[nelem][ion];
00088 change = MAX2(change, one );
00089
00090 if( change>bigchange )
00091 {
00092 bigchange = change;
00093 abundold = OldFracs[nelem][ion]/Abund;
00094 abundnew = dense.xIonDense[nelem][ion]/Abund;
00095 }
00096 }
00097
00098 OldFracs[nelem][ion] = dense.xIonDense[nelem][ion];
00099 }
00100
00101 if( change < delta )
00102 {
00103 lgConverg_v = true;
00104 }
00105 else
00106 {
00107 lgConverg_v = false;
00108 conv.BadConvIoniz[0] = abundold;
00109 conv.BadConvIoniz[1] = abundnew;
00110 ASSERT( abundold>0. && abundnew>0. );
00111 }
00112 }
00113 else
00114 {
00115 for( ion=0; ion <= (nelem+1); ++ion )
00116 {
00117 OldFracs[nelem][ion] = dense.xIonDense[nelem][ion];
00118 }
00119
00120 lgConverg_v = true;
00121 }
00122
00123
00124 if( lgPrint )
00125 {
00126 fprintf(ioQQQ," element %li converged? %c ",nelem, TorF(lgConverg_v));
00127 for( ion=0; ion<(nelem+1); ++ion )
00128 {
00129 fprintf(ioQQQ,"\t%.2e", dense.xIonDense[nelem][ion]/dense.gas_phase[nelem]);
00130 }
00131 fprintf(ioQQQ,"\n");
00132 }
00133 return( lgConverg_v );
00134 }
00135
00136
00137
00138
00139 int ConvBase(
00140
00141
00142 long loopi )
00143 {
00144 double O_HIonRate_New , O_HIonRate_Old;
00145 double HeatOld,
00146 EdenTrue_old,
00147 EdenFromMolecOld,
00148 EdenFromGrainsOld,
00149 HeatingOld ,
00150 CoolingOld;
00151 realnum hmole_save[N_H_MOLEC];
00152 static double SecondOld;
00153 static long int nzoneOTS=-1;
00154 # define LOOP_ION_LIMIT 10
00155 long int nelem,
00156 ion,
00157 loop_ion,
00158 i,
00159 ipISO;
00160 static double SumOTS=0. , OldSumOTS[2]={0.,0.};
00161 double save_iso_grnd[NISO][LIMELM];
00162
00163 DEBUG_ENTRY( "ConvBase()" );
00164
00165 #if 0
00166 if( loopi == 0 )
00167 {
00168 OldSumOTS[0] = 0.;
00169 OldSumOTS[1] = 0.;
00170 SumOTS = 0.;
00171 nzoneOTS = -1;
00172 }
00173 #endif
00174
00175
00176
00177
00178 ASSERT( fp_equal( phycon.te, thermal.te_update ) );
00179
00180
00181
00182 fnzone = (double)nzone + (double)conv.nPres2Ioniz/100.;
00183
00184
00185
00186
00187 PresTotCurrent();
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 if( conv.nTotalIoniz )
00199 {
00200 if( eden_sum() )
00201 {
00202
00203 ++conv.nTotalIoniz;
00204 return 1;
00205 }
00206 }
00207
00208
00209
00210 EdenTrue_old = dense.EdenTrue;
00211 EdenFromMolecOld = co.comole_eden;
00212 EdenFromGrainsOld = gv.TotalEden;
00213 HeatingOld = thermal.htot;
00214 CoolingOld = thermal.ctot;
00215
00216
00217 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00218 {
00219 for( nelem=ipISO; nelem<LIMELM;++nelem )
00220 {
00221 if( dense.lgElmtOn[nelem] )
00222 {
00223
00224 save_iso_grnd[ipISO][nelem] = StatesElem[ipISO][nelem][0].Pop;
00225 }
00226 }
00227 }
00228
00229 for( i=0; i < mole.num_comole_calc; i++ )
00230 {
00231 COmole[i]->comole_save = COmole[i]->hevmol;
00232 }
00233
00234 for( i=0; i < N_H_MOLEC; i++ )
00235 {
00236 hmole_save[i] = hmi.Hmolec[i];
00237 }
00238
00239 if( loopi==0 )
00240 {
00241
00242 OldSumOTS[0] = 0.;
00243 OldSumOTS[1] = 0.;
00244 }
00245
00246 if( trace.lgTrace )
00247 {
00248 fprintf( ioQQQ,
00249 " ConvBase called. %.2f Te:%.3e HI:%.3e HII:%.3e H2:%.3e Ne:%.3e htot:%.3e CSUP:%.2e Conv?%c\n",
00250 fnzone,
00251 phycon.te,
00252 dense.xIonDense[ipHYDROGEN][0],
00253 dense.xIonDense[ipHYDROGEN][1],
00254 hmi.H2_total,
00255 dense.eden,
00256 thermal.htot,
00257 secondaries.csupra[ipHYDROGEN][0] ,
00258 TorF(conv.lgConvIoniz) );
00259 }
00260
00261 conv.lgConvIoniz = true;
00262
00263
00264 HeatZero();
00265
00266
00267
00268
00269 if( !conv.nTotalIoniz )
00270 {
00271 conv.lgConvIoniz = false;
00272 strcpy( conv.chConvIoniz, "first call" );
00273 }
00274
00275
00276
00277 conv.lgIonStageTrimed = false;
00278
00279
00280
00281
00282
00283 opac.lgRedoStatic = false;
00284 if(
00285
00286 !opac.lgOpacStatic ||
00287
00288 conv.lgSearch ||
00289
00290 conv.nPres2Ioniz == 0 )
00291 {
00292
00293 opac.lgRedoStatic = true;
00294 }
00295
00296
00297 ion_recom_calculate();
00298
00299
00300
00301
00302
00303
00304
00305 if( conv.nTotalIoniz )
00306 {
00307 bool lgIonizTrimCalled = false;
00308 static long int nZoneCalled = 0;
00309
00310 fixit();
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 if( conv.nTotalIoniz>2 &&
00324
00325
00326 ( conv.lgSearch || nZoneCalled!=nzone) )
00327 {
00328 lgIonizTrimCalled = true;
00329 for( nelem=ipHELIUM; nelem<LIMELM; ++nelem )
00330 {
00331 if( dense.lgElmtOn[nelem] )
00332 {
00333
00334
00335 ion_trim(nelem);
00336 }
00337 }
00338 nZoneCalled = nzone;
00339 }
00340
00341
00342 # if !defined(NDEBUG)
00343
00344 for( nelem=ipHELIUM; nelem<LIMELM; ++nelem)
00345 {
00346 if( dense.lgElmtOn[nelem] )
00347 {
00348 for( ion=0; ion<dense.IonLow[nelem]; ++ion )
00349 {
00350 ASSERT( dense.xIonDense[nelem][ion] == 0. );
00351 }
00352
00353 for( ion=dense.IonLow[nelem]; ion<=dense.IonHigh[nelem]; ++ion )
00354 {
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 ASSERT( conv.lgSearch || !lgIonizTrimCalled ||
00369
00370 (ion==0 && dense.IonHigh[nelem]==0 ) ||
00371 dense.xIonDense[nelem][ion] >= SMALLFLOAT ||
00372 dense.xIonDense[nelem][ion]/dense.gas_phase[nelem] >= SMALLFLOAT );
00373 }
00374 for( ion=dense.IonHigh[nelem]+1; ion<nelem+1; ++ion )
00375 {
00376 ASSERT( ion >= 0 );
00377 ASSERT( dense.xIonDense[nelem][ion] == 0. );
00378 }
00379 }
00380 }
00381 # endif
00382 }
00383
00384
00385 if( conv.lgIonStageTrimed )
00386 {
00387
00388
00389 conv.lgConvIoniz = false;
00390 strcpy( conv.chConvIoniz, "IonTrimmed" );
00391 }
00392
00393
00394 if( dynamics.lgAdvection )
00395 DynaIonize();
00396
00397
00398
00399
00400 loop_ion = 0;
00401 do
00402 {
00403
00404 if( trace.nTrConvg>=4 )
00405 {
00406
00407 fprintf( ioQQQ,
00408 " ConvBase4 ionization driver loop_ion %li converged? %c reason not converged %s\n" ,
00409 loop_ion ,
00410 TorF( conv.lgConvIoniz) ,
00411 conv.chConvIoniz );
00412 }
00413
00414
00415
00416
00417
00418 if( loop_ion )
00419 conv.lgConvIoniz = true;
00420
00421
00422
00423
00424
00425 ChargTranEval( &O_HIonRate_Old );
00426
00427 CO_update_species_cache();
00428
00429 hmole_reactions();
00430
00431 co.nitro_dissoc_rate = 0;
00432
00433
00434 CO_update_rks();
00435
00436
00437
00438 GrainDrive();
00439
00440
00441
00442 iso_solve( ipH_LIKE );
00443
00444
00445
00446 highen();
00447
00448
00449 atmdat_3body();
00450
00451
00452 atmdat_DielSupres();
00453
00454
00455
00456 iso_solve( ipHE_LIKE );
00457
00458
00459
00460
00461 if( lgAbort )
00462 {
00463 ++conv.nTotalIoniz;
00464 return 1;
00465 }
00466
00467
00468
00469
00470
00471 if( opac.lgRedoStatic )
00472 {
00473
00474 for( nelem=0; nelem< LIMELM; ++nelem )
00475 {
00476 for( ion=0; ion<nelem+1; ++ion )
00477 {
00478 ionbal.UTA_ionize_rate[nelem][ion] = 0.;
00479 ionbal.UTA_heat_rate[nelem][ion] = 0.;
00480 }
00481 }
00482
00483
00484 if( ionbal.lgInnerShellLine_on )
00485 {
00486 for( i=0; i<nUTA; ++i )
00487 {
00488 if( UTALines[i].Emis->Aul > 0. )
00489 {
00490
00491
00492 double rateone = UTALines[i].Emis->pump * -UTALines[i].Coll.cs;
00493 ionbal.UTA_ionize_rate[UTALines[i].Hi->nelem-1][UTALines[i].Hi->IonStg-1] += rateone;
00494
00495 ionbal.UTA_heat_rate[UTALines[i].Hi->nelem-1][UTALines[i].Hi->IonStg-1] += rateone*UTALines[i].Coll.heat;
00496 {
00497
00498
00499 enum {DEBUG_LOC=false};
00500
00501 if( DEBUG_LOC )
00502 {
00503 fprintf(ioQQQ,"DEBUG UTA %3i %3i %.3f %.2e %.2e %.2e\n",
00504 UTALines[i].Hi->nelem , UTALines[i].Hi->IonStg , UTALines[i].WLAng ,
00505 rateone, UTALines[i].Coll.heat,
00506 UTALines[i].Coll.heat*dense.xIonDense[UTALines[i].Hi->nelem-1][UTALines[i].Hi->IonStg-1] );
00507 }
00508 }
00509 }
00510 }
00511 }
00512 }
00513
00514
00515 IonHelium();
00516
00517
00518
00519
00520
00521
00522
00523 IonCarbo();
00524 IonOxyge();
00525 IonNitro();
00526 IonSilic();
00527 IonSulph();
00528 IonChlor();
00529
00530 CO_drive();
00531 if( !conv.nPres2Ioniz || rfield.lgIonizReevaluate ||
00532 conv.lgIonStageTrimed || conv.lgSearch )
00533 {
00534 IonLithi();
00535 IonBeryl();
00536 IonBoron();
00537
00538
00539
00540
00541
00542
00543 IonFluor();
00544 IonNeon();
00545 IonSodiu();
00546 IonMagne();
00547 IonAlumi();
00548 IonPhosi();
00549 IonArgon();
00550 IonPotas();
00551 IonCalci();
00552 IonScand();
00553 IonTitan();
00554 IonVanad();
00555 IonChrom();
00556 IonManga();
00557 IonIron();
00558 IonCobal();
00559 IonNicke();
00560 IonCoppe();
00561 IonZinc();
00562 }
00563
00564
00565
00566
00567
00568 for( nelem=ipHYDROGEN; nelem < LIMELM; nelem++ )
00569 {
00570 if( dense.lgSetIoniz[nelem] )
00571 {
00572 dense.IonLow[nelem] = 0;
00573 dense.IonHigh[nelem] = nelem + 1;
00574 while( dense.SetIoniz[nelem][dense.IonLow[nelem]] == 0. )
00575 ++dense.IonLow[nelem];
00576 while( dense.SetIoniz[nelem][dense.IonHigh[nelem]] == 0. )
00577 --dense.IonHigh[nelem];
00578 }
00579 }
00580
00581
00582 ChargTranEval( &O_HIonRate_New );
00583
00584
00585
00586
00587
00588 for( nelem=ipHELIUM; nelem<LIMELM; ++nelem )
00589 {
00590 if( !lgIonizConverg(nelem, 0.05 ,false ) )
00591 {
00592 conv.lgConvIoniz = false;
00593 sprintf( conv.chConvIoniz , "%2s ion" , elementnames.chElementSym[nelem] );
00594 }
00595 }
00596
00597 if( fabs(EdenTrue_old - dense.EdenTrue)/SDIV(dense.EdenTrue) > conv.EdenErrorAllowed/2. )
00598 {
00599 conv.lgConvIoniz = false;
00600 sprintf( conv.chConvIoniz , "EdTr cng" );
00601 conv.BadConvIoniz[0] = EdenTrue_old;
00602 conv.BadConvIoniz[1] = dense.EdenTrue;
00603 }
00604 ++loop_ion;
00605 }
00606
00607 while( !conv.lgConvIoniz && loop_ion < LOOP_ION_LIMIT && rfield.lgIonizReevaluate);
00608
00609
00610
00611
00612 thermal.char_tran_heat = ChargTranSumHeat();
00613
00614 thermal.char_tran_cool = MAX2(0. , -thermal.char_tran_heat );
00615 thermal.char_tran_heat = MAX2(0. , thermal.char_tran_heat );
00616
00617
00618
00619 CoolEvaluate(&thermal.ctot );
00620
00621
00622 HeatOld = thermal.htot;
00623
00624
00625
00626
00627 SecondOld = secondaries.csupra[ipHYDROGEN][0];
00628
00629
00630
00631 HeatSum();
00632
00633
00634
00635
00636
00637 if( (secondaries.csupra[ipHYDROGEN][0]>SMALLFLOAT) && (secondaries.sec2total>0.001) &&
00638 fabs( 1. - SecondOld/SDIV(secondaries.csupra[ipHYDROGEN][0]) ) > 0.1 &&
00639 SecondOld > 0. && secondaries.csupra[ipHYDROGEN][0] > 0.)
00640 {
00641
00642 conv.lgConvIoniz = false;
00643 strcpy( conv.chConvIoniz, "SecIonRate" );
00644 conv.BadConvIoniz[0] = SecondOld;
00645 conv.BadConvIoniz[1] = secondaries.csupra[ipHYDROGEN][0];
00646 }
00647
00648 # if 0
00649 static realnum hminus_old=0.;
00650
00651 if( conv.nTotalIoniz )
00652 {
00653 if( fabs( hminus_old-hmi.Hmolec[ipMHm])/SDIV(hmi.Hmolec[ipMHm]) >
00654 conv.EdenErrorAllowed/4. )
00655 conv.lgConvIoniz = false;
00656 strcpy( conv.chConvIoniz, "Big H- chn" );
00657 conv.BadConvIoniz[0] = hminus_old;
00658 conv.BadConvIoniz[1] = hmi.Hmolec[ipMHm];
00659 }
00660 hminus_old = hmi.Hmolec[ipMHm];
00661 # endif
00662
00663 if( HeatOld > 0. && !thermal.lgTemperatureConstant )
00664 {
00665
00666 if( fabs(1.-thermal.htot/HeatOld) > conv.HeatCoolRelErrorAllowed*.5 )
00667 {
00668 conv.lgConvIoniz = false;
00669 strcpy( conv.chConvIoniz, "Big d Heat" );
00670 conv.BadConvIoniz[0] = HeatOld;
00671 conv.BadConvIoniz[1] = thermal.htot;
00672 }
00673 }
00674
00675
00676 if( lgAbort )
00677 {
00678
00679 return 1;
00680 }
00681
00682
00683
00684
00685 if( !conv.nPres2Ioniz || rfield.lgOpacityReevaluate || conv.lgIonStageTrimed )
00686 OpacityAddTotal();
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 if( !conv.nPres2Ioniz || rfield.lgOpacityReevaluate || rfield.lgIonizReevaluate ||
00697 conv.lgIonStageTrimed || conv.lgSearch || nzone!=nzoneOTS )
00698 {
00699 RT_OTS();
00700 nzoneOTS = nzone;
00701
00702
00703 OldSumOTS[0] = OldSumOTS[1];
00704 OldSumOTS[1] = SumOTS;
00705
00706
00707
00708
00709
00710
00711
00712 RT_OTS_Update(&SumOTS , 0.20 );
00713
00714 }
00715 else
00716 SumOTS = 0.;
00717
00718
00719 if( SumOTS> 0. )
00720 {
00721
00722
00723
00724 if( fabs(1.-OldSumOTS[1]/SumOTS) > conv.EdenErrorAllowed )
00725 {
00726
00727
00728 if( loopi > 1 )
00729 {
00730
00731 if( (OldSumOTS[0]-OldSumOTS[1]) * ( OldSumOTS[1] - SumOTS ) < 0. )
00732 {
00733
00734
00735 conv.lgOscilOTS = true;
00736 }
00737 }
00738
00739 conv.lgConvIoniz = false;
00740 strcpy( conv.chConvIoniz, "OTSRatChng" );
00741 conv.BadConvIoniz[0] = OldSumOTS[1];
00742 conv.BadConvIoniz[1] = SumOTS;
00743 }
00744
00745
00746 if( ( trace.lgTrace && trace.lgOTSBug ) ||
00747 ( trace.nTrConvg && trace.lgOTSBug ) )
00748 {
00749 RT_OTS_PrtRate(SumOTS*0.05 , 'b' );
00750 }
00751
00752
00753
00754 {
00755
00756
00757 enum {DEBUG_LOC=false};
00758
00759 if( DEBUG_LOC && (nzone>110) )
00760 {
00761 # if 0
00762 # include "lines_service.h"
00763 DumpLine( &Transitions[ipH_LIKE][ipHYDROGEN][2][0] );
00764 # endif
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 }
00775 }
00776 }
00777 {
00778
00779
00780 enum {DEBUG_LOC=false};
00781
00782 if( DEBUG_LOC && (nzone>200) )
00783 {
00784 fprintf(ioQQQ,"debug otsss\t%li\t%.3e\t%.3e\t%.3e\n",
00785 nzone,
00786 Transitions[0][1][15][3].Emis->ots,
00787 TauLines[26].Emis->ots,
00788 opac.opacity_abs[2069]);
00789 }
00790 }
00791
00792
00793 if( trace.lgTrace && trace.lgOTSBug )
00794 {
00795
00796
00797
00798 RT_OTS_PrtRate(SumOTS*0.05 , 'b' );
00799 }
00800
00801
00802
00803
00804 if( conv.nPres2Ioniz && !conv.lgSearch )
00805 {
00806 RT_line_all(false , false );
00807 }
00808 else
00809 {
00810 RT_line_all(true , false );
00811 }
00812
00813
00814
00815
00816 PresTotCurrent();
00817
00818 if( trace.lgTrace )
00819 {
00820 fprintf( ioQQQ,
00821 " ConvBase return. %.2f Te:%.3e HI:%.3e HII:%.3e H2:%.3e Ne:%.3e htot:%.3e CSUP:%.2e Conv?%c\n",
00822 fnzone,
00823 phycon.te,
00824 dense.xIonDense[ipHYDROGEN][0],
00825 dense.xIonDense[ipHYDROGEN][1],
00826 hmi.H2_total,
00827 dense.eden,
00828 thermal.htot,
00829 secondaries.csupra[ipHYDROGEN][0] ,
00830 TorF(conv.lgConvIoniz) );
00831 }
00832
00833
00834
00835 for( nelem=ipHYDROGEN; nelem<LIMELM; ++nelem )
00836 {
00837
00838
00839 if( dense.lgElmtOn[nelem] && !dense.lgSetIoniz[nelem])
00840 {
00841
00842
00843 double sum = dense.xMolecules[nelem];
00844 for( ion=0; ion<nelem+2; ++ion )
00845 {
00846 sum += dense.xIonDense[nelem][ion];
00847 }
00848 ASSERT( sum > SMALLFLOAT );
00849
00853
00854
00855
00856
00857
00858
00859
00860 if( fabs(sum-dense.gas_phase[nelem])/SDIV(sum) > 2e-2 )
00861 {
00862
00863
00864
00865
00866
00867 conv.lgConvIoniz = false;
00868 strcpy( conv.chConvIoniz, "CO con4" );
00869 sprintf( conv.chConvIoniz, "COnelem%2li",nelem );
00870 conv.BadConvIoniz[0] = sum;
00871 conv.BadConvIoniz[1] = dense.gas_phase[nelem];
00872 }
00873 }
00874 }
00875
00876
00877
00878
00879
00880
00881
00882 ++conv.nPres2Ioniz;
00883
00884
00885
00886
00887 if( conv.nPres2Ioniz > conv.limPres2Ioniz && nzone > 0)
00888 {
00889 fprintf(ioQQQ,"PROBLEM ConvBase sets lgAbort since nPres2Ioniz exceeds limPres2Ioniz.\n");
00890 fprintf(ioQQQ,"Their values are %li and %li \n",conv.nPres2Ioniz , conv.limPres2Ioniz);
00891 lgAbort = true;
00892
00893 return 1;
00894 }
00895
00896
00897
00898 if( eden_sum() )
00899 {
00900
00901 return 1;
00902 }
00903
00905 if( fabs(EdenTrue_old - dense.EdenTrue)/dense.EdenTrue > conv.EdenErrorAllowed/2. )
00906 {
00907 conv.lgConvIoniz = false;
00908 sprintf( conv.chConvIoniz, "eden chng" );
00909 conv.BadConvIoniz[0] = EdenTrue_old;
00910 conv.BadConvIoniz[1] = dense.EdenTrue;
00911 }
00912
00913
00914 if( fabs(EdenFromMolecOld - co.comole_eden)/dense.EdenTrue > conv.EdenErrorAllowed/2. )
00915 {
00916 conv.lgConvIoniz = false;
00917 sprintf( conv.chConvIoniz, "edn chnCO" );
00918 conv.BadConvIoniz[0] = EdenFromMolecOld;
00919 conv.BadConvIoniz[1] = dense.EdenTrue;
00920 }
00921
00922
00923 if( fabs(EdenFromGrainsOld - gv.TotalEden)/dense.EdenTrue > conv.EdenErrorAllowed/2. )
00924 {
00925 conv.lgConvIoniz = false;
00926 sprintf( conv.chConvIoniz, "edn grn e" );
00927 conv.BadConvIoniz[0] = EdenFromGrainsOld;
00928 conv.BadConvIoniz[1] = gv.TotalEden;
00929 }
00930
00931
00932 if( !thermal.lgTemperatureConstant )
00933 {
00934 if( fabs(HeatingOld - thermal.htot)/thermal.htot > conv.HeatCoolRelErrorAllowed/2. )
00935 {
00936 conv.lgConvIoniz = false;
00937 sprintf( conv.chConvIoniz, "heat chg" );
00938 conv.BadConvIoniz[0] = HeatingOld;
00939 conv.BadConvIoniz[1] = thermal.htot;
00940 }
00941
00942 if( fabs(CoolingOld - thermal.ctot)/thermal.ctot > conv.HeatCoolRelErrorAllowed/2. )
00943 {
00944 conv.lgConvIoniz = false;
00945 sprintf( conv.chConvIoniz, "cool chg" );
00946 conv.BadConvIoniz[0] = CoolingOld;
00947 conv.BadConvIoniz[1] = thermal.ctot;
00948 }
00949 }
00950
00951
00952 if( fabs( (EdenFromMolecOld-EdenFromGrainsOld) - (co.comole_eden-gv.TotalEden) )/dense.eden >
00953 conv.EdenErrorAllowed/4. )
00954 {
00955 conv.lgConvIoniz = false;
00956 sprintf( conv.chConvIoniz, "edn grn e" );
00957 conv.BadConvIoniz[0] = (EdenFromMolecOld-EdenFromGrainsOld);
00958 conv.BadConvIoniz[1] = (co.comole_eden-gv.TotalEden);
00959 }
00960
00961
00962 for( i=0; i < mole.num_comole_calc; ++i )
00963 {
00964 if( dense.lgElmtOn[COmole[i]->nelem_hevmol] && COmole[i]->hevmol>SMALLFLOAT )
00965 {
00966 if( fabs(COmole[i]->hevmol-COmole[i]->comole_save)/dense.gas_phase[COmole[i]->nelem_hevmol]-1. >
00967 conv.EdenErrorAllowed/2.)
00968 {
00969 conv.lgConvIoniz = false;
00970 sprintf( conv.chConvIoniz, "ch %s",COmole[i]->label );
00971 conv.BadConvIoniz[0] = COmole[i]->comole_save/dense.gas_phase[COmole[i]->nelem_hevmol];
00972 conv.BadConvIoniz[1] = COmole[i]->hevmol/dense.gas_phase[COmole[i]->nelem_hevmol];
00973 }
00974 }
00975 }
00976
00977
00978 for( i=0; i < N_H_MOLEC; ++i )
00979 {
00980 if( fabs(hmi.Hmolec[i]-hmole_save[i])/dense.gas_phase[ipHYDROGEN]-1. >
00981 conv.EdenErrorAllowed/2.)
00982 {
00983 conv.lgConvIoniz = false;
00984 sprintf( conv.chConvIoniz, "ch %s",hmi.chLab[i] );
00985 conv.BadConvIoniz[0] = hmole_save[i]/dense.gas_phase[ipHYDROGEN];
00986 conv.BadConvIoniz[1] = hmi.Hmolec[i]/dense.gas_phase[ipHYDROGEN];
00987 }
00988 }
00989
00990
00991
00992
00993 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00994 {
00995 for( nelem=ipISO; nelem<LIMELM;++nelem )
00996 {
00997 if( dense.lgElmtOn[nelem] )
00998 {
00999
01000
01001 if( dense.xIonDense[nelem][nelem+1-ipISO]/dense.gas_phase[nelem] > 1e-5 )
01002 {
01003 if( fabs(StatesElem[ipISO][nelem][0].Pop-save_iso_grnd[ipISO][nelem])/SDIV(StatesElem[ipISO][nelem][0].Pop)-1. >
01004 conv.EdenErrorAllowed)
01005 {
01006 conv.lgConvIoniz = false;
01007 sprintf( conv.chConvIoniz,"iso %3li%li",ipISO, nelem );
01008 conv.BadConvIoniz[0] = save_iso_grnd[ipISO][nelem]/SDIV(StatesElem[ipISO][nelem][0].Pop);
01009 fixit();
01010 conv.BadConvIoniz[1] = StatesElem[ipISO][nelem][0].Pop/SDIV(StatesElem[ipISO][nelem][0].Pop);
01011 }
01012 }
01013
01014 }
01015 }
01016 }
01017
01018
01019
01020
01021
01022
01023 ++conv.nTotalIoniz;
01024
01025
01026
01027 if(StopCalc.nTotalIonizStop && conv.nTotalIoniz> StopCalc.nTotalIonizStop )
01028 {
01029
01030 fprintf(ioQQQ , "ABORT flag set since STOP nTotalIoniz was set and reached.\n");
01031 return 1;
01032 }
01033
01034 if( punch.lgTraceConvergeBase )
01035 {
01036 if( iteration > 1 && punch.lgTraceConvergeBaseHash )
01037 {
01038 static int iter_punch=-1;
01039 if( iteration !=iter_punch )
01040 fprintf( punch.ipDRout, "%s\n",punch.chHashString );
01041 iter_punch = iteration;
01042 }
01043
01044 fprintf( punch.ipTraceConvergeBase,
01045 "%li\t%.4e\t%.4e\t%.4e\n",
01046 nzone , thermal.htot , thermal.ctot , dense.eden );
01047 }
01048
01049 return 0;
01050 }