283 {
284
285 std::ifstream gasfile;
286
287 gasfile.open(filename.c_str());
288
289 if (!gasfile.is_open()) {
291 std::cerr << " Gas file could not be opened.\n";
292 return false;
293 }
294
295 char line[256];
296 char* token;
297
298
299 std::string gasBits = "";
300
301
302 const int nMagboltzGases = 60;
303 std::vector<double> mixture(nMagboltzGases);
304 for (int i = nMagboltzGases; i--;) mixture[i] = 0.;
305
306 int excCount = 0;
307 int ionCount = 0;
308
309 int eFieldRes = 1;
310 int bFieldRes = 1;
311 int angRes = 1;
312
313 int versionNumber = 12;
314
315
316 bool atTables = false;
317 while (!atTables) {
318 gasfile.getline(line, 256);
319 if (strncmp(line, " The gas tables follow:", 8) == 0 ||
320 strncmp(line, "The gas tables follow:", 7) == 0) {
321 atTables = true;
323 std::cout << " Entering tables.\n";
324 getchar();
325 }
326 }
328 std::cout << " Line: " << line << "\n";
329 getchar();
330 }
331 if (!atTables) {
332 token = strtok(line, " :,%");
333 while (token != NULL) {
334 if (
m_debug) std::cout <<
" Token: " << token <<
"\n";
335 if (strcmp(token, "Version") == 0) {
336 token = strtok(NULL, " :,%");
337 versionNumber = atoi(token);
338
339 if (versionNumber != 10 && versionNumber != 11 &&
340 versionNumber != 12) {
342 std::cerr << " The file has version number " << versionNumber
343 << ".\n";
344 std::cerr << " Files written in this format cannot be read.\n";
345 gasfile.close();
346 return false;
347 } else {
349 std::cout << " Version: " << versionNumber << "\n";
350 }
351 } else if (strcmp(token, "GASOK") == 0) {
352
353
354 token = strtok(NULL, " :,%\t");
355 token = strtok(NULL, " :,%\t");
356 gasBits += token;
357 } else if (strcmp(token, "Identifier") == 0) {
358
359 std::string identifier = "";
360 token = strtok(NULL, "\n");
361 if (token != NULL) identifier += token;
364 std::cout << " Identifier:\n";
365 std::cout << " " << token << "\n";
366 }
367 } else if (strcmp(token, "Dimension") == 0) {
368 token = strtok(NULL, " :,%\t");
369 if (strcmp(token, "F") == 0) {
371 } else {
373 }
374 token = strtok(NULL, " :,%\t");
375 eFieldRes = atoi(token);
376
377 if (eFieldRes <= 0) {
379 std::cerr << " Number of E fields out of range.\n";
380 gasfile.close();
381 return false;
382 }
383 token = strtok(NULL, " :,%\t");
384 angRes = atoi(token);
385
388 std::cerr << " Number of E-B angles out of range.\n";
389 gasfile.close();
390 return false;
391 }
392
393 token = strtok(NULL, " :,%\t");
394 bFieldRes = atoi(token);
395
396 if (
m_map2d && bFieldRes <= 0) {
398 std::cerr << " Number of B fields out of range.\n";
399 gasfile.close();
400 return false;
401 }
402
409
410
411
412 token = strtok(NULL, " :,%\t");
414 std::cout << " " << token << "\n";
415 }
416 int nexc = atoi(token);
420 }
421
422 token = strtok(NULL, " :,%\t");
423 int nion = atoi(token);
427 }
429 std::cout << " Finished initializing excitation/ionisation"
430 << " structs.\n";
431 }
432 } else if (strcmp(token, "E") == 0) {
433 token = strtok(NULL, " :,%");
434 if (strcmp(token, "fields") == 0) {
435 for (int i = 0; i < eFieldRes; i++) {
437 }
438 }
439 } else if (strcmp(token, "E-B") == 0) {
440 token = strtok(NULL, " :,%");
441 if (strcmp(token, "angles") == 0) {
442 for (int i = 0; i < angRes; i++) {
444 }
445 }
446 } else if (strcmp(token, "B") == 0) {
447 token = strtok(NULL, " :,%");
448 if (strcmp(token, "fields") == 0) {
449 double bstore = 0.;
450 for (int i = 0; i < bFieldRes; i++) {
451
452 gasfile >> bstore;
454 }
455 }
456 } else if (strcmp(token, "Mixture") == 0) {
457 for (int i = 0; i < nMagboltzGases; ++i) {
458 gasfile >> mixture[i];
459 }
460 } else if (strcmp(token, "Excitation") == 0) {
461
462 token = strtok(NULL, " :,%");
463
464 token = strtok(NULL, " :,%");
466
467 token = strtok(NULL, " :,%");
469
470 token = strtok(NULL, " :,%");
472 if (versionNumber >= 11) {
473
474 token = strtok(NULL, " :,%");
476
477 token = strtok(NULL, " :,%");
479 } else {
482 }
483
484 excCount++;
485 } else if (strcmp(token, "Ionisation") == 0) {
486
487 token = strtok(NULL, " :,%");
488
489 token = strtok(NULL, " :,%");
491
492 token = strtok(NULL, " :,%");
494
495 ionCount++;
496 }
497 token = strtok(NULL, " :,%");
498 }
499 }
500 }
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
523 std::cout << " GASOK bits: " << gasBits << "\n";
524 }
525
526 if (gasBits[0] == 'T') {
529 } else {
532 }
533 if (gasBits[1] == 'T') {
536 } else {
539 }
540 if (gasBits[2] == 'T') {
543 } else {
546 }
547 if (gasBits[3] == 'T') {
551 } else {
555 }
556
557 if (gasBits[5] == 'T') {
560 } else {
563 }
564
565 if (gasBits[7] == 'T') {
568 } else {
571 }
572 if (gasBits[8] == 'T') {
575 } else {
578 }
579 if (gasBits[9] == 'T') {
582 } else {
585 }
586 if (gasBits[10] == 'T') {
589 } else {
592 }
593 if (gasBits[11] == 'T') {
596 } else {
599 }
600
601
602 if (gasBits[14] == 'T') {
605 0.);
606 } else {
609 }
610 if (gasBits[15] == 'T') {
613 0.);
614 } else {
617 }
618
619
620 std::vector<std::string> gasnames;
621 gasnames.clear();
622 std::vector<double> percentages;
623 percentages.clear();
624 bool gasMixOk = true;
625 unsigned int gasCount = 0;
626 for (int i = 0; i < nMagboltzGases; ++i) {
627 if (mixture[i] > 0.) {
628 std::string gasname = "";
629 if (!
GetGasName(i + 1, versionNumber, gasname)) {
631 std::cerr << " Unknown gas (gas number ";
632 std::cerr << i + 1 << ")\n";
633 gasMixOk = false;
634 break;
635 }
636 gasnames.push_back(gasname);
637 percentages.push_back(mixture[i]);
638 ++gasCount;
639 }
640 }
643 std::cerr << " Gas mixture has " << gasCount << " components.\n";
644 std::cerr <<
" Number of gases is limited to " <<
m_nMaxGases <<
".\n";
645 gasMixOk = false;
646 } else if (gasCount == 0) {
648 std::cerr << " Gas mixture is not defined (zero components).\n";
649 gasMixOk = false;
650 }
651 double sum = 0.;
652 for (unsigned int i = 0; i < gasCount; ++i) sum += percentages[i];
653 if (gasMixOk && sum != 100.) {
655 std::cerr << " Percentages are not normalized to 100.\n";
656 for (unsigned int i = 0; i < gasCount; ++i) percentages[i] *= 100. / sum;
657 }
658
659
661
662 if (gasMixOk) {
668 gas[i] = gasnames[i];
669 fraction[i] = percentages[i] / 100.;
671 }
673 std::cout <<
" Gas composition set to " <<
m_name;
675 std::cout <<
" (" <<
fraction[0] * 100;
677 std::cout <<
"/" <<
fraction[i] * 100;
678 }
679 std::cout << ")";
680 }
681 std::cout << "\n";
682 } else {
684 std::cerr << " Gas composition could not be established.\n";
685 }
686
689 std::cout << " Reading gas tables.\n";
690 }
691
692
693
694 double ve = 0., vb = 0., vexb = 0.;
695
696 double lor = 0.;
697
698 double dl = 0., dt = 0.;
699
700 double alpha = 0., alpha0 = 0., eta = 0.;
701
702 double mu = 0., diss = 0.;
703 double ionDiffLong = 0., ionDiffTrans = 0.;
704 double diff = 0.;
705 double rate = 0.;
706 double waste = 0.;
707
711 std::cout << " Gas table is 3D.\n";
712 }
713 for (int i = 0; i < eFieldRes; i++) {
714 for (int j = 0; j < angRes; j++) {
715 for (int k = 0; k < bFieldRes; k++) {
716
717 gasfile >> ve >> vb >> vexb;
718
719 ve *= 1.e-3;
720 vb *= 1.e-3;
721 vexb *= 1.e-3;
725
726 gasfile >> dl >> dt;
729
730 gasfile >>
alpha >> alpha0 >> eta;
734 }
737 }
738
739 gasfile >> mu;
740
741 mu *= 1.e-3;
743
744 gasfile >> lor;
745
746 gasfile >> diss;
748
749 for (int l = 0; l < 6; l++) {
750 gasfile >> diff;
752 }
753
755 gasfile >> rate;
757 }
758
760 gasfile >> rate;
762 }
763 }
764 }
765 }
766 } else {
769 std::cout << " Gas table is 1D.\n";
770 }
771 for (int i = 0; i < eFieldRes; i++) {
772 if (
m_debug) std::cout <<
" Done table: " << i <<
"\n";
773
774 gasfile >> ve >> waste >> vb >> waste >> vexb >> waste;
775 ve *= 1.e-3;
776 vb *= 1.e-3;
777 vexb *= 1.e-3;
781
782 gasfile >> dl >> waste >> dt >> waste;
785
786 gasfile >>
alpha >> waste >> alpha0 >> eta >> waste;
790 }
793 }
794
795 gasfile >> mu >> waste;
796 mu *= 1.e-3;
798
799 gasfile >> lor >> waste;
800
801 gasfile >> diss >> waste;
803
804 for (int j = 0; j < 6; j++) {
805 gasfile >> diff >> waste;
807 }
808
810 gasfile >> rate >> waste;
812 }
813
815 gasfile >> rate >> waste;
817 }
818 }
819 }
820 if (
m_debug) std::cout <<
" Done with gas tables.\n";
821
822
823 int hExtrap[13], lExtrap[13];
824
825 int interpMeth[13];
826
827
828 bool done = false;
829 while (!done) {
830 gasfile.getline(line, 256);
831 token = strtok(line, " :,%=\t");
832 while (token != NULL) {
833 if (strcmp(token, "H") == 0) {
834 token = strtok(NULL, " :,%=\t");
835 for (int i = 0; i < 13; i++) {
836 token = strtok(NULL, " :,%=\t");
837 if (token != NULL) hExtrap[i] = atoi(token);
838 }
839 } else if (strcmp(token, "L") == 0) {
840 token = strtok(NULL, " :,%=\t");
841 for (int i = 0; i < 13; i++) {
842 token = strtok(NULL, " :,%=\t");
843 if (token != NULL) lExtrap[i] = atoi(token);
844 }
845 } else if (strcmp(token, "Thresholds") == 0) {
846 token = strtok(NULL, " :,%=\t");
848 token = strtok(NULL, " :,%=\t");
850 token = strtok(NULL, " :,%=\t");
852 } else if (strcmp(token, "Interp") == 0) {
853 for (int i = 0; i < 13; i++) {
854 token = strtok(NULL, " :,%=\t");
855 if (token != NULL) interpMeth[i] = atoi(token);
856 }
857 } else if (strcmp(token, "A") == 0) {
858 token = strtok(NULL, " :,%=\t");
859
860
861
862 } else if (strcmp(token, "Z") == 0) {
863
864 token = strtok(NULL, " :,%=\t");
865
866
867 } else if (strcmp(token, "EMPROB") == 0) {
868
869 token = strtok(NULL, " :,%=\t");
870
871
872 } else if (strcmp(token, "EPAIR") == 0) {
873
874 token = strtok(NULL, " :,%=\t");
875
876
877 } else if (strcmp(token, "Ion") == 0) {
878
879 token = strtok(NULL, " :,%=\t");
880 token = strtok(NULL, " :,%=\t");
881 if (token != NULL) ionDiffLong = atof(token);
882 token = strtok(NULL, " :,%=\t");
883 if (token != NULL) ionDiffTrans = atof(token);
884 } else if (strcmp(token, "CMEAN") == 0) {
885
886 token = strtok(NULL, " :,%=\t");
887
888
889 } else if (strcmp(token, "RHO") == 0) {
890
891 token = strtok(NULL, " :,%=\t");
892
893
894 } else if (strcmp(token, "PGAS") == 0) {
895 token = strtok(NULL, " :,%=\t");
896 double pTorr = 760.;
897 if (token != NULL) pTorr = atof(token);
899 } else if (strcmp(token, "TGAS") == 0) {
900 token = strtok(NULL, " :,%=\t");
901 double tKelvin = 293.15;
902 if (token != NULL) tKelvin = atof(token);
904 done = true;
905 break;
906 } else {
907 done = true;
908 break;
909 }
910 token = strtok(NULL, " :,%=\t");
911 }
912 }
913
914 gasfile.close();
915
916
919
920
921 for (int i = eFieldRes; i--;) {
923 }
924
927 for (int i = eFieldRes; i--;) {
928 for (int j = angRes; j--;) {
929 for (int k = bFieldRes; k--;) {
932 }
935 }
937 for (int l = 6; l--;) {
939 }
940 }
943 }
946 }
949 }
950 }
951 }
952 }
953
954
958
971
975
982
983
984 if (ionDiffLong > 0.) {
987 for (int i = eFieldRes; i--;) {
988 for (int j = angRes; j--;) {
989 for (int k = bFieldRes; k--;) {
991 }
992 }
993 }
994 } else {
997 }
998 if (ionDiffTrans > 0.) {
1001 for (int i = eFieldRes; i--;) {
1002 for (int j = angRes; j--;) {
1003 for (int k = bFieldRes; k--;) {
1005 }
1006 }
1007 }
1008 } else {
1011 }
1012
1015 std::cout << " Gas file sucessfully read.\n";
1016 }
1017
1018 return true;
1019}
DoubleAc sqrt(const DoubleAc &f)
std::vector< std::vector< std::vector< std::vector< double > > > > tabIonRates
bool GetGasName(const int gasnumber, const int version, std::string &gasname)
std::vector< std::vector< std::vector< double > > > tabTownsendNoPenning
std::vector< std::vector< std::vector< std::vector< double > > > > tabExcRates
bool m_hasElectronDiffTens
unsigned int m_extrLowMobility
unsigned int m_intpDiffusion
unsigned int m_extrLowDiffusion
void InitParamTensor(const unsigned int &eRes, const unsigned int &bRes, const unsigned int &aRes, const unsigned int &tRes, std::vector< std::vector< std::vector< std::vector< double > > > > &tab, const double &val)
bool m_hasElectronDiffTrans
bool m_hasElectronTownsend
std::vector< double > bFields
std::vector< std::vector< std::vector< double > > > tabElectronVelocityB
unsigned int m_extrHighAttachment
unsigned int m_intpMobility
unsigned int m_intpAttachment
bool m_hasElectronVelocityB
unsigned int m_extrHighDiffusion
std::vector< double > eFields
std::vector< std::vector< std::vector< double > > > tabIonDissociation
unsigned int m_extrHighMobility
std::vector< std::vector< std::vector< double > > > tabElectronVelocityE
unsigned int m_intpTownsend
unsigned int m_extrLowAttachment
std::vector< double > bAngles
unsigned int m_extrHighDissociation
unsigned int m_intpVelocity
std::vector< std::vector< std::vector< double > > > tabElectronDiffLong
std::vector< std::vector< std::vector< double > > > tabElectronAttachment
unsigned int m_extrLowVelocity
unsigned int m_extrHighTownsend
unsigned int m_extrHighVelocity
unsigned int m_extrLowTownsend
std::vector< std::vector< std::vector< double > > > tabIonDiffTrans
unsigned int m_extrLowDissociation
std::vector< std::vector< std::vector< std::vector< double > > > > tabElectronDiffTens
bool m_hasElectronVelocityExB
std::vector< std::vector< std::vector< double > > > tabIonMobility
int thrElectronAttachment
bool m_hasElectronDiffLong
void InitParamArrays(const unsigned int &eRes, const unsigned int &bRes, const unsigned int &aRes, std::vector< std::vector< std::vector< double > > > &tab, const double &val)
std::vector< std::vector< std::vector< double > > > tabIonDiffLong
bool m_hasIonDissociation
unsigned int m_intpDissociation
bool m_hasElectronVelocityE
bool m_hasElectronAttachment
std::vector< std::vector< std::vector< double > > > tabElectronDiffTrans
std::vector< std::vector< std::vector< double > > > tabElectronVelocityExB