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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef THREE_D_LIST_CLASS
00039 #define THREE_D_LIST_CLASS
00040
00041 #include "list_2d.hpp"
00042 #include "endl_formats.hpp"
00043 #include "global_params.hpp"
00044 #include "mappings.hpp"
00045 #include "nuclei.hpp"
00046
00047 extern ENDLClass ENDL;
00048 extern GlobalParameterClass Global;
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 enum Direction{ Straight, Forward, Transition, Both_ways };
00060
00061
00062
00063
00064
00065
00066
00067
00068 class Geometry
00069 {
00070 public:
00071 Direction fastest;
00072 Direction slowest;
00073 };
00074
00075
00076
00077 template< class one_d > class three_d_link : public two_d_list< one_d >
00078 {
00079 public:
00080 int Num_mu;
00081
00082 mappings map;
00083
00084 Geometry geom_;
00085
00086
00087 three_d_link()
00088 {
00089
00090 Num_mu = static_cast<int>( Global.Value("num_mu_3d"));
00091 }
00092
00093
00094
00095 virtual typename three_d_link< one_d >::iterator
00096 new_one_d( typename three_d_link< one_d >::iterator where ) = 0;
00097
00098
00099
00100
00101 void make_cos_link(double e_in, two_d_table::iterator new_cos)
00102 {
00103 new_cos->E_in() = e_in;
00104
00105
00106 for( typename three_d_link::iterator this_cos = three_d_link::begin();
00107 this_cos != three_d_link::end(); ++this_cos )
00108 {
00109
00110 double prob = this_cos->get_norm();
00111 dd_link new_link(this_cos->mu(), prob);
00112 new_cos->insert(new_cos->end(), new_link);
00113
00114
00115 if( prob == 0.0 )
00116 {
00117 this_cos->begin( )->y = 1.0;
00118 this_cos->widen_jumps( );
00119 this_cos->renorm( );
00120 }
00121 else
00122 {
00123 this_cos->renorm(prob);
00124 }
00125 }
00126
00127
00128 new_cos->renorm();
00129 }
00130
00131
00132 void get_geom( double first_E_out, double last_E_out )
00133
00134
00135 {
00136 if(last_E_out <= first_E_out)
00137 {
00138 SevereError( "three_d_link::get_geom", "energies out of order" );
00139 }
00140
00141 if(last_E_out > map.E_transl)
00142 {
00143 geom_.fastest = Both_ways;
00144 if(first_E_out == 0.0)
00145 {
00146 geom_.slowest = Straight;
00147 }
00148 else if(first_E_out < map.E_transl)
00149 {
00150
00151 geom_.slowest = Forward;
00152 }
00153 else if(first_E_out == map.E_transl)
00154 {
00155 geom_.slowest = Transition;
00156 }
00157 else
00158 {
00159
00160 geom_.slowest = Both_ways;
00161 }
00162 }
00163 else if(last_E_out == map.E_transl)
00164 {
00165 geom_.fastest = Transition;
00166 if(first_E_out == 0.0)
00167 {
00168 geom_.slowest = Straight;
00169 }
00170 else
00171 {
00172 geom_.slowest = Forward;
00173 }
00174 }
00175 else
00176 {
00177 geom_.fastest = Forward;
00178 if(first_E_out == 0.0)
00179 {
00180 geom_.slowest = Straight;
00181 }
00182 else
00183 {
00184 geom_.slowest = Forward;
00185 }
00186 }
00187 }
00188
00189 void full_range( double last_E_out )
00190
00191
00192
00193
00194
00195 {
00196
00197
00198 const double dmu = 1.0/Num_mu;
00199 double this_mu;
00200
00201 for (int count = -Num_mu; count <= Num_mu; ++count)
00202 {
00203 this_mu = count*dmu;
00204
00205 typename three_d_link< one_d >::iterator mu_link =
00206 new_one_d( three_d_link::end( ) );
00207 mu_link->mu() = this_mu;
00208
00209
00210 double E_dummy;
00211 double max_E_out;
00212 map.get_E_range(last_E_out, this_mu, &E_dummy, &max_E_out);
00213
00214
00215 mu_link->one_E_row( 0.0, max_E_out );
00216 }
00217 }
00218
00219
00220 void all_both_ways( double first_E_out, double last_E_out )
00221
00222
00223
00224
00225
00226 {
00227
00228
00229 const double dmu = 1.0/Num_mu;
00230 double mu;
00231
00232 for (int count = -Num_mu; count <= Num_mu; ++count)
00233 {
00234 mu = count*dmu;
00235
00236 typename three_d_link< one_d >::iterator mu_link =
00237 new_one_d( three_d_link::end( ) );
00238 mu_link->mu() = mu;
00239
00240
00241 double E_dummy;
00242 double max_E_out;
00243 map.get_E_range(last_E_out, mu, &E_dummy, &max_E_out);
00244
00245
00246 double min_E_out;
00247 map.get_E_range(first_E_out, mu, &E_dummy, &min_E_out);
00248
00249
00250 mu_link->one_E_row( min_E_out, max_E_out );
00251 }
00252 }
00253
00254
00255 void both_ways_trans( double first_E_out, double last_E_out )
00256
00257
00258
00259
00260
00261 {
00262
00263
00264 const double dmu = 1.0/Num_mu;
00265 double mu;
00266
00267 for (int count = -Num_mu; count <= Num_mu; ++count)
00268 {
00269 mu = count*dmu;
00270
00271 typename three_d_link< one_d >::iterator mu_link =
00272 new_one_d( three_d_link::end( ) );
00273 mu_link->mu() = mu;
00274
00275
00276 double E_dummy;
00277 double max_E_out;
00278 map.get_E_range(last_E_out, mu, &E_dummy, &max_E_out);
00279
00280 double min_E_out;
00281 if(mu <= 0)
00282 {
00283 min_E_out = 0.0;
00284 }
00285 else
00286 {
00287
00288 map.get_E_range(first_E_out, mu, &E_dummy, &min_E_out);
00289 }
00290
00291
00292 mu_link->one_E_row( min_E_out, max_E_out );
00293 }
00294 }
00295
00296
00297 void full_trans( double last_E_out )
00298
00299
00300
00301
00302
00303 {
00304
00305
00306
00307
00308 double mu_floor = 0.001;
00309 const double dmu = (1.0 - mu_floor)/(2*Num_mu);
00310 double mu;
00311
00312 for (int count = 0; count <= 2*Num_mu; ++count)
00313 {
00314 mu = mu_floor + count*dmu;
00315
00316 typename three_d_link< one_d >::iterator mu_link =
00317 new_one_d( three_d_link::end( ) );
00318 mu_link->mu() = mu;
00319
00320 double E_dummy;
00321 double max_E_out;
00322 map.get_E_range(last_E_out, mu, &E_dummy, &max_E_out);
00323
00324
00325 mu_link->one_E_row( 0.0, max_E_out );
00326 }
00327 }
00328
00329
00330 void full_forward( double first_E_out, double last_E_out )
00331
00332
00333
00334
00335
00336
00337 {
00338
00339
00340
00341
00342 double mu_floor = map.get_min_mu(last_E_out);
00343 double dmu = (1.0 - mu_floor);
00344
00345 mu_floor += dmu * 0.001;
00346 dmu = (1.0 - mu_floor)/(2*Num_mu);
00347 double mu;
00348
00349 for (int count = 0; count <= 2*Num_mu; ++count)
00350 {
00351 mu = mu_floor + count*dmu;
00352 if ( mu > 1.0 )
00353 {
00354 mu = 1.0;
00355 }
00356
00357 typename three_d_link< one_d >::iterator mu_link =
00358 new_one_d( three_d_link::end( ) );
00359 mu_link->mu() = mu;
00360
00361
00362
00363 double min_E_out;
00364 double max_E_out;
00365 map.get_E_range(last_E_out, mu, &min_E_out, &max_E_out);
00366
00367
00368 mu_link->one_E_row( min_E_out, max_E_out );
00369 }
00370 }
00371
00372
00373 void forward_hole( double first_E_out, double last_E_out )
00374
00375
00376
00377
00378
00379
00380 {
00381
00382
00383
00384
00385 double mu_floor = map.get_min_mu(last_E_out);
00386 double dmu = (1.0 - mu_floor);
00387
00388 mu_floor += dmu * 0.001;
00389 dmu = (1.0 - mu_floor)/(2*Num_mu);
00390 double mu;
00391
00392
00393
00394 double mu_split = map.get_min_mu(first_E_out);
00395
00396 for (int count = 0; count <= 2*Num_mu; ++count)
00397 {
00398 mu = mu_floor + count*dmu;
00399
00400 typename three_d_link< one_d >::iterator mu_link =
00401 new_one_d( three_d_link::end( ) );
00402 mu_link->mu() = mu;
00403
00404
00405
00406 double min_E_out;
00407 double max_E_out;
00408 map.get_E_range(last_E_out, mu, &min_E_out,
00409 &max_E_out);
00410
00411
00412 if(mu < mu_split)
00413 {
00414 mu_link->one_E_row( min_E_out, max_E_out );
00415 }
00416 else
00417 {
00418
00419 double min_E_split;
00420 double max_E_split;
00421 map.get_E_range(first_E_out, mu, &min_E_split, &max_E_split);
00422
00423
00424 mu_link->one_E_row( min_E_out, min_E_split );
00425
00426
00427 double de = 0.0001*(max_E_split - min_E_split);
00428 dd_link e_out_link(min_E_split + de, 0.0);
00429 mu_link->insert(mu_link->end(), e_out_link);
00430 e_out_link.x = max_E_split - de;
00431 mu_link->insert(mu_link->end(), e_out_link);
00432
00433
00434 mu_link->one_E_row( max_E_split, max_E_out );
00435 }
00436 }
00437 }
00438
00439
00440 void trans_hole( double first_E_out, double last_E_out )
00441
00442
00443
00444
00445
00446
00447 {
00448
00449
00450
00451
00452 double mu_floor = 0.001;
00453 const double dmu = (1.0 - mu_floor)/(2*Num_mu);
00454 double mu;
00455
00456
00457
00458 double mu_split = map.get_min_mu(first_E_out);
00459
00460 for (int count = 0; count <= 2*Num_mu; ++count)
00461 {
00462 mu = mu_floor + count*dmu;
00463
00464 typename three_d_link< one_d >::iterator mu_link =
00465 new_one_d( three_d_link::end( ) );
00466 mu_link->mu() = mu;
00467
00468
00469
00470 double E_dummy;
00471 double max_E_out;
00472 map.get_E_range(last_E_out, mu, &E_dummy, &max_E_out);
00473
00474
00475 if(mu < mu_split)
00476 {
00477 mu_link->one_E_row( 0.0, max_E_out );
00478 }
00479 else
00480 {
00481 double min_E_split;
00482 double max_E_split;
00483
00484 map.get_E_range(first_E_out, mu, &min_E_split, &max_E_split);
00485
00486
00487 mu_link->one_E_row( 0.0, min_E_split );
00488
00489
00490 double de = 0.0001*(max_E_split - min_E_split);
00491 dd_link e_out_link(min_E_split + de, 0.0);
00492 mu_link->insert(mu_link->end(), e_out_link);
00493 e_out_link.x = max_E_split - de;
00494 mu_link->insert(mu_link->end(), e_out_link);
00495
00496
00497 mu_link->one_E_row( max_E_split, max_E_out );
00498 }
00499 }
00500 }
00501
00502
00503 void both_ways_hole( double first_E_out, double last_E_out )
00504
00505
00506
00507
00508
00509
00510
00511 {
00512
00513
00514
00515 const double dmu = 1.0/Num_mu;
00516 double mu;
00517
00518
00519 double mu_split = map.get_min_mu(first_E_out);
00520
00521 for (int count = -Num_mu; count <= Num_mu; ++count)
00522 {
00523 mu = count*dmu;
00524
00525 typename three_d_link< one_d >::iterator mu_link =
00526 new_one_d( three_d_link::end( ) );
00527 mu_link->mu() = mu;
00528
00529
00530
00531 double E_dummy;
00532 double max_E_out;
00533 map.get_E_range(last_E_out, mu, &E_dummy, &max_E_out);
00534
00535
00536 if(mu < mu_split)
00537 {
00538 mu_link->one_E_row( 0.0, max_E_out );
00539 }
00540 else
00541 {
00542
00543
00544 double min_E_split;
00545 double max_E_split;
00546 map.get_E_range(first_E_out, mu, &min_E_split,
00547 &max_E_split);
00548
00549
00550 mu_link->one_E_row( 0.0, min_E_split );
00551
00552
00553 double de = 0.0001*(max_E_split - min_E_split);
00554 dd_link e_out_link(min_E_split + de, 0.0);
00555 mu_link->insert(mu_link->end(), e_out_link);
00556 e_out_link.x = max_E_split;
00557 mu_link->insert(mu_link->end(), e_out_link);
00558
00559
00560 mu_link->one_E_row( max_E_split, max_E_out );
00561 }
00562 }
00563 }
00564
00565 void write_endl_link( fstream& endl_file )
00566
00567 {
00568 double old_mu = -2.0;
00569 for( typename three_d_link< one_d >::iterator cos_link = three_d_link::begin();
00570 cos_link != three_d_link::end(); ++cos_link )
00571 {
00572
00573 if(cos_link->mu() == old_mu)
00574 {
00575 Warning("three_d_list::write_endl_link",
00576 pastenum("Widen the jump in cos_list at E_in: ", three_d_link::E_in( ) )+
00577 pastenum(" mu: ",old_mu));
00578 }
00579 old_mu = cos_link->mu();
00580 double old_x = -2.0;
00581 for(dd_list::iterator E_out_link = cos_link->begin();
00582 E_out_link != cos_link->end();
00583 ++E_out_link)
00584 {
00585
00586 if(E_out_link->x == old_x)
00587 {
00588 Warning("three_d_link::write_endl_link",
00589 pastenum("Widen the jump in one_d_list at E_in: ", three_d_link::E_in( ) )+
00590 pastenum(" mu: ",old_mu)+
00591 pastenum(" x: ",old_x));
00592 }
00593 old_x = E_out_link->x;
00594 endl_file << ENDL.data( three_d_link::E_in(),
00595 cos_link->mu(),
00596 E_out_link->E_out(),
00597 E_out_link->y )
00598 <<endl;
00599 }
00600 }
00601 }
00602 };
00603
00604
00605
00606
00607
00608 template < class two_d > class three_d_list :
00609 public list< two_d >
00610 {
00611 private:
00612 bool debug_on;
00613
00614 public:
00615 vector<int> NBT;
00616 vector<int> INT;
00617
00618 Target A;
00619 Projectile a;
00620 Residual B;
00621 Product b;
00622 Compound C;
00623
00624 two_d_table cosines;
00625
00626
00627 three_d_list()
00628 {
00629
00630 debug_on = false;
00631 }
00632
00633
00634
00635 void print()
00636 {
00637
00638 for( typename three_d_list< two_d >::iterator this_e_in = three_d_list::begin();
00639 this_e_in != three_d_list::end(); ++this_e_in )
00640 {
00641 cout<<"----------- E_in = " << ENDL.data( this_e_in->E_in()) << endl;
00642 this_e_in->print();
00643 }
00644 cout << endl;
00645 }
00646
00647
00648
00649
00650
00651 void prune_zeronorm_data() {
00652 if ( cosines.size() != three_d_list::size() )
00653 SevereError("three_d_list::prune_zeronorm_data",
00654 "three_d_list and three_d_list::cosines dimensions don't match");
00655 typename three_d_list< two_d >::iterator it1 = three_d_list::begin();
00656 two_d_table::iterator it2 = cosines.begin();
00657 for ( int iE = 0; iE < three_d_list::size(); ++iE )
00658 {
00659 if ( ( it1 == three_d_list::end() ) || (it2 == cosines.end() ) )
00660 SevereError( "three_d_list::prune_zeronorm_data","fell off edge of E list!");
00661 // Loop through list of mu's in lock-step,
00662 // removing zero norm sets as we go
00663 typename two_d::iterator it1mu = it1->begin();
00664 dd_list::iterator it2mu = it2->begin();
00665 for ( int imu = 0; imu < it1->size(); ++imu )
00666 {
00667 if ( ( it1mu == it1->end() ) || (it2mu == it2->end() ) )
00668 SevereError( "three_d_list::prune_zeronorm_data","fell off edge of mu list!");
00669 if ( it2mu->y <= 0. )
00670 {
00671 cout << "Norm 0.0? "<<it2mu->y<<endl;
00672 it1mu = it1->erase(it1mu);
00673 it2mu = it2->erase(it2mu);
00674 }
00675 else
00676 {
00677 ++it1mu;
00678 ++it2mu;
00679 }
00680 }
00681 it1->renorm();
00682 ++it1;
00683 ++it2;
00684 }
00685 cosines.renorm();
00686 }
00687 */
00688
00689
00690
00691 void write_endl()
00692 {
00693
00694 ENDL.set_I_number( 3 );
00695
00696 fstream endl_file;
00697 string file_name = ENDL.file_name;
00698
00699
00700
00701
00702
00703 if(three_d_list::empty())
00704 {
00705 Warning("three_d_list::write_endl","The file "+file_name+" is empty.");
00706 return;
00707 }
00708
00709 if ( ENDL.new_file() )
00710 {
00711 endl_file.open(file_name.c_str(),ios::out);
00712 Info("three_d_list::write_endl","Opening ENDL file "+file_name);
00713 }
00714 else
00715 {
00716 endl_file.open(file_name.c_str(),ios::out|ios::app);
00717 Info("three_d_list::write_endl","Appending ENDL file "+file_name);
00718 }
00719
00720
00721 endl_file<<ENDL.header_line_1<<endl;
00722 endl_file<<ENDL.header_line_2<<endl;
00723 endl_file.setf(ios::scientific,ios::floatfield);
00724
00725
00726 double old_E_in = -1.0;
00727 for( typename three_d_list< two_d >::iterator E_in_link = three_d_list::begin( );
00728 E_in_link != three_d_list::end( );
00729 ++E_in_link )
00730 {
00731
00732 if( E_in_link->E_in( ) == old_E_in )
00733 {
00734 Warning("three_d_list::write_endl",
00735 pastenum("Widen the jump in three_d_list at E_in: ",old_E_in));
00736 }
00737 old_E_in = E_in_link->E_in( );
00738
00739
00740 E_in_link->write_endl_link( endl_file );
00741 }
00742
00743
00744 endl_file<<ENDL.eof_line<<endl;
00745
00746
00747 Info("three_d_list::write_endl","Closing ENDL file "+file_name);
00748 endl_file.close();
00749
00750
00751 cosines.write_endl(1);
00752 }
00753
00754 };
00755
00756 #endif