/** \file config.cpp * * Function implementations for the class config. * */ #include "molecules.hpp" /************************************* Functions for class config ***************************/ /** Constructor for config file class. */ config::config() { mainname = (char *) MallocString(sizeof(char)*255,"config constructor: mainname"); defaultpath = (char *) MallocString(sizeof(char)*255,"config constructor: mainname"); pseudopotpath = (char *) MallocString(sizeof(char)*255,"config constructor: mainname"); strcpy(mainname,"pcp"); strcpy(defaultpath,"not specified "); strcpy(pseudopotpath,"not specified "); ProcPEGamma=8; ProcPEPsi=1; DoOutVis=0; DoOutMes=1; DoOutNICS=0; DoOutOrbitals=0; DoOutCurrent=0; DoPerturbation=0; DoFullCurrent=0; CommonWannier=0; SawtoothStart=0.01; VectorPlane=0; VectorCut=0; UseAddGramSch=1; Seed=1; MaxOuterStep=0; Deltat=0; OutVisStep=10; OutSrcStep=5; TargetTemp=0.00095004455; ScaleTempStep=25; MaxPsiStep=0; EpsWannier=1e-7; MaxMinStep=100; RelEpsTotalEnergy=1e-7; RelEpsKineticEnergy=1e-5; MaxMinStopStep=1; MaxMinGapStopStep=0; MaxInitMinStep=100; InitRelEpsTotalEnergy=1e-5; InitRelEpsKineticEnergy=1e-4; InitMaxMinStopStep=1; InitMaxMinGapStopStep=0; //BoxLength[NDIM*NDIM]; ECut=128.; MaxLevel=5; RiemannTensor=0; LevRFactor=0; RiemannLevel=0; Lev0Factor=2; RTActualUse=0; PsiType=0; MaxPsiDouble=0; PsiMaxNoUp=0; PsiMaxNoDown=0; AddPsis=0; RCut=20.; StructOpt=0; IsAngstroem=1; RelativeCoord=0; MaxTypes=0; }; /** Destructor for config file class. */ config::~config() { Free((void **)&mainname, "config::~config: *mainname"); Free((void **)&defaultpath, "config::~config: *defaultpath"); Free((void **)&pseudopotpath, "config::~config: *pseudopotpath"); }; /** Displays menu for editing each entry of the config file. * Nothing fancy here, just lots of cout << Verbose(0)s for the menu and a switch/case * for each entry of the config file structure. */ void config::Edit(molecule *mol) { char choice; do { cout << Verbose(0) << "===========EDIT CONFIGURATION============================" << endl; cout << Verbose(0) << " A - mainname (prefix for all runtime files)" << endl; cout << Verbose(0) << " B - Default path (for runtime files)" << endl; cout << Verbose(0) << " C - Path of pseudopotential files" << endl; cout << Verbose(0) << " D - Number of coefficient sharing processes" << endl; cout << Verbose(0) << " E - Number of wave function sharing processes" << endl; cout << Verbose(0) << " F - 0: Don't output density for OpenDX, 1: do" << endl; cout << Verbose(0) << " G - 0: Don't output physical data, 1: do" << endl; cout << Verbose(0) << " H - 0: Don't output densities of each unperturbed orbital for OpenDX, 1: do" << endl; cout << Verbose(0) << " I - 0: Don't output current density for OpenDX, 1: do" << endl; cout << Verbose(0) << " J - 0: Don't do the full current calculation, 1: do" << endl; cout << Verbose(0) << " K - 0: Don't do perturbation calculation to obtain susceptibility and shielding, 1: do" << endl; cout << Verbose(0) << " L - 0: Wannier centres as calculated, 1: common centre for all, 2: unite centres according to spread, 3: cell centre, 4: shifted to nearest grid point" << endl; cout << Verbose(0) << " M - Absolute begin of unphysical sawtooth transfer for position operator within cell" << endl; cout << Verbose(0) << " N - (0,1,2) x,y,z-plane to do two-dimensional current vector cut" << endl; cout << Verbose(0) << " O - Absolute position along vector cut axis for cut plane" << endl; cout << Verbose(0) << " P - Additional Gram-Schmidt-Orthonormalization to stabilize numerics" << endl; cout << Verbose(0) << " Q - Initial integer value of random number generator" << endl; cout << Verbose(0) << " R - for perturbation 0, for structure optimization defines upper limit of iterations" << endl; cout << Verbose(0) << " T - Output visual after ...th step" << endl; cout << Verbose(0) << " U - Output source densities of wave functions after ...th step" << endl; cout << Verbose(0) << " X - minimization iterations per wave function, if unsure leave at default value 0" << endl; cout << Verbose(0) << " Y - tolerance value for total spread in iterative Jacobi diagonalization" << endl; cout << Verbose(0) << " Z - Maximum number of minimization iterations" << endl; cout << Verbose(0) << " a - Relative change in total energy to stop min. iteration" << endl; cout << Verbose(0) << " b - Relative change in kinetic energy to stop min. iteration" << endl; cout << Verbose(0) << " c - Check stop conditions every ..th step during min. iteration" << endl; cout << Verbose(0) << " e - Maximum number of minimization iterations during initial level" << endl; cout << Verbose(0) << " f - Relative change in total energy to stop min. iteration during initial level" << endl; cout << Verbose(0) << " g - Relative change in kinetic energy to stop min. iteration during initial level" << endl; cout << Verbose(0) << " h - Check stop conditions every ..th step during min. iteration during initial level" << endl; cout << Verbose(0) << " j - six lower diagonal entries of matrix, defining the unit cell" << endl; cout << Verbose(0) << " k - Energy cutoff of plane wave basis in Hartree" << endl; cout << Verbose(0) << " l - Maximum number of levels in multi-level-ansatz" << endl; cout << Verbose(0) << " m - Factor by which grid nodes increase between standard and upper level" << endl; cout << Verbose(0) << " n - 0: Don't use RiemannTensor, 1: Do" << endl; cout << Verbose(0) << " o - Factor by which grid nodes increase between Riemann and standard(?) level" << endl; cout << Verbose(0) << " p - Number of Riemann levels" << endl; cout << Verbose(0) << " r - 0: Don't Use RiemannTensor, 1: Do" << endl; cout << Verbose(0) << " s - 0: Doubly occupied orbitals, 1: Up-/Down-Orbitals" << endl; cout << Verbose(0) << " t - Number of orbitals (depends pn SpinType)" << endl; cout << Verbose(0) << " u - Number of SpinUp orbitals (depends on SpinType)" << endl; cout << Verbose(0) << " v - Number of SpinDown orbitals (depends on SpinType)" << endl; cout << Verbose(0) << " w - Number of additional, unoccupied orbitals" << endl; cout << Verbose(0) << " x - radial cutoff for ewald summation in Bohrradii" << endl; cout << Verbose(0) << " y - 0: Don't do structure optimization beforehand, 1: Do" << endl; cout << Verbose(0) << " z - 0: Units are in Bohr radii, 1: units are in Aengstrom" << endl; cout << Verbose(0) << " i - 0: Coordinates given in file are absolute, 1: ... are relative to unit cell" << endl; cout << Verbose(0) << "=========================================================" << endl; cout << Verbose(0) << "INPUT: "; cin >> choice; switch (choice) { case 'A': // mainname cout << Verbose(0) << "Old: " << config::mainname << "\t new: "; cin >> config::mainname; break; case 'B': // defaultpath cout << Verbose(0) << "Old: " << config::defaultpath << "\t new: "; cin >> config::defaultpath; break; case 'C': // pseudopotpath cout << Verbose(0) << "Old: " << config::pseudopotpath << "\t new: "; cin >> config::pseudopotpath; break; case 'D': // ProcPEGamma cout << Verbose(0) << "Old: " << config::ProcPEGamma << "\t new: "; cin >> config::ProcPEGamma; break; case 'E': // ProcPEPsi cout << Verbose(0) << "Old: " << config::ProcPEPsi << "\t new: "; cin >> config::ProcPEPsi; break; case 'F': // DoOutVis cout << Verbose(0) << "Old: " << config::DoOutVis << "\t new: "; cin >> config::DoOutVis; break; case 'G': // DoOutMes cout << Verbose(0) << "Old: " << config::DoOutMes << "\t new: "; cin >> config::DoOutMes; break; case 'H': // DoOutOrbitals cout << Verbose(0) << "Old: " << config::DoOutOrbitals << "\t new: "; cin >> config::DoOutOrbitals; break; case 'I': // DoOutCurrent cout << Verbose(0) << "Old: " << config::DoOutCurrent << "\t new: "; cin >> config::DoOutCurrent; break; case 'J': // DoFullCurrent cout << Verbose(0) << "Old: " << config::DoFullCurrent << "\t new: "; cin >> config::DoFullCurrent; break; case 'K': // DoPerturbation cout << Verbose(0) << "Old: " << config::DoPerturbation << "\t new: "; cin >> config::DoPerturbation; break; case 'L': // CommonWannier cout << Verbose(0) << "Old: " << config::CommonWannier << "\t new: "; cin >> config::CommonWannier; break; case 'M': // SawtoothStart cout << Verbose(0) << "Old: " << config::SawtoothStart << "\t new: "; cin >> config::SawtoothStart; break; case 'N': // VectorPlane cout << Verbose(0) << "Old: " << config::VectorPlane << "\t new: "; cin >> config::VectorPlane; break; case 'O': // VectorCut cout << Verbose(0) << "Old: " << config::VectorCut << "\t new: "; cin >> config::VectorCut; break; case 'P': // UseAddGramSch cout << Verbose(0) << "Old: " << config::UseAddGramSch << "\t new: "; cin >> config::UseAddGramSch; break; case 'Q': // Seed cout << Verbose(0) << "Old: " << config::Seed << "\t new: "; cin >> config::Seed; break; case 'R': // MaxOuterStep cout << Verbose(0) << "Old: " << config::MaxOuterStep << "\t new: "; cin >> config::MaxOuterStep; break; case 'T': // OutVisStep cout << Verbose(0) << "Old: " << config::OutVisStep << "\t new: "; cin >> config::OutVisStep; break; case 'U': // OutSrcStep cout << Verbose(0) << "Old: " << config::OutSrcStep << "\t new: "; cin >> config::OutSrcStep; break; case 'X': // MaxPsiStep cout << Verbose(0) << "Old: " << config::MaxPsiStep << "\t new: "; cin >> config::MaxPsiStep; break; case 'Y': // EpsWannier cout << Verbose(0) << "Old: " << config::EpsWannier << "\t new: "; cin >> config::EpsWannier; break; case 'Z': // MaxMinStep cout << Verbose(0) << "Old: " << config::MaxMinStep << "\t new: "; cin >> config::MaxMinStep; break; case 'a': // RelEpsTotalEnergy cout << Verbose(0) << "Old: " << config::RelEpsTotalEnergy << "\t new: "; cin >> config::RelEpsTotalEnergy; break; case 'b': // RelEpsKineticEnergy cout << Verbose(0) << "Old: " << config::RelEpsKineticEnergy << "\t new: "; cin >> config::RelEpsKineticEnergy; break; case 'c': // MaxMinStopStep cout << Verbose(0) << "Old: " << config::MaxMinStopStep << "\t new: "; cin >> config::MaxMinStopStep; break; case 'e': // MaxInitMinStep cout << Verbose(0) << "Old: " << config::MaxInitMinStep << "\t new: "; cin >> config::MaxInitMinStep; break; case 'f': // InitRelEpsTotalEnergy cout << Verbose(0) << "Old: " << config::InitRelEpsTotalEnergy << "\t new: "; cin >> config::InitRelEpsTotalEnergy; break; case 'g': // InitRelEpsKineticEnergy cout << Verbose(0) << "Old: " << config::InitRelEpsKineticEnergy << "\t new: "; cin >> config::InitRelEpsKineticEnergy; break; case 'h': // InitMaxMinStopStep cout << Verbose(0) << "Old: " << config::InitMaxMinStopStep << "\t new: "; cin >> config::InitMaxMinStopStep; break; case 'j': // BoxLength cout << Verbose(0) << "enter lower triadiagonalo form of basis matrix" << endl << endl; for (int i=0;i<6;i++) { cout << Verbose(0) << "Cell size" << i << ": "; cin >> mol->cell_size[i]; } break; case 'k': // ECut cout << Verbose(0) << "Old: " << config::ECut << "\t new: "; cin >> config::ECut; break; case 'l': // MaxLevel cout << Verbose(0) << "Old: " << config::MaxLevel << "\t new: "; cin >> config::MaxLevel; break; case 'm': // RiemannTensor cout << Verbose(0) << "Old: " << config::RiemannTensor << "\t new: "; cin >> config::RiemannTensor; break; case 'n': // LevRFactor cout << Verbose(0) << "Old: " << config::LevRFactor << "\t new: "; cin >> config::LevRFactor; break; case 'o': // RiemannLevel cout << Verbose(0) << "Old: " << config::RiemannLevel << "\t new: "; cin >> config::RiemannLevel; break; case 'p': // Lev0Factor cout << Verbose(0) << "Old: " << config::Lev0Factor << "\t new: "; cin >> config::Lev0Factor; break; case 'r': // RTActualUse cout << Verbose(0) << "Old: " << config::RTActualUse << "\t new: "; cin >> config::RTActualUse; break; case 's': // PsiType cout << Verbose(0) << "Old: " << config::PsiType << "\t new: "; cin >> config::PsiType; break; case 't': // MaxPsiDouble cout << Verbose(0) << "Old: " << config::MaxPsiDouble << "\t new: "; cin >> config::MaxPsiDouble; break; case 'u': // PsiMaxNoUp cout << Verbose(0) << "Old: " << config::PsiMaxNoUp << "\t new: "; cin >> config::PsiMaxNoUp; break; case 'v': // PsiMaxNoDown cout << Verbose(0) << "Old: " << config::PsiMaxNoDown << "\t new: "; cin >> config::PsiMaxNoDown; break; case 'w': // AddPsis cout << Verbose(0) << "Old: " << config::AddPsis << "\t new: "; cin >> config::AddPsis; break; case 'x': // RCut cout << Verbose(0) << "Old: " << config::RCut << "\t new: "; cin >> config::RCut; break; case 'y': // StructOpt cout << Verbose(0) << "Old: " << config::StructOpt << "\t new: "; cin >> config::StructOpt; break; case 'z': // IsAngstroem cout << Verbose(0) << "Old: " << config::IsAngstroem << "\t new: "; cin >> config::IsAngstroem; break; case 'i': // RelativeCoord cout << Verbose(0) << "Old: " << config::RelativeCoord << "\t new: "; cin >> config::RelativeCoord; break; }; } while (choice != 'q'); }; /** Tests whether a given configuration file adhears to old or new syntax. * \param *file input file stream being the opened config file * \param *periode pointer to a periodentafel class with all elements * \param *mol pointer to molecule containing all atoms of the molecule * \return 0 - old syntax, 1 - new syntax, -1 - unknown syntax */ int config::TestSyntax(ifstream *file, periodentafel *periode, molecule *mol) { int test; // search file for keyword: ProcPEGamma (new syntax) if (ParseForParameter(1,file,"ProcPEGamma", 0, 1, 1, int_type, &test, 1, optional)) return 1; // search file for keyword: ProcsGammaPsi (old syntax) if (ParseForParameter(1,file,"ProcsGammaPsi", 0, 1, 1, int_type, &test, 1, optional)) return 0; return -1; } /** Returns private config::IsAngstroem. * \return IsAngstroem */ bool config::GetIsAngstroem() const { return (IsAngstroem == 1); }; /** Returns private config::*defaultpath. * \return *defaultpath */ char * config::GetDefaultPath() const { return defaultpath; }; /** Returns private config::*defaultpath. * \return *defaultpath */ void config::SetDefaultPath(const char *path) { strcpy(defaultpath, path); }; /** Initializes config file structure by loading elements from a give file. * \param *file input file stream being the opened config file * \param *periode pointer to a periodentafel class with all elements * \param *mol pointer to molecule containing all atoms of the molecule */ void config::Load(ifstream *file, periodentafel *periode, molecule *mol) { // ParseParameters /* Oeffne Hauptparameterdatei */ int di; double BoxLength[9]; string zeile; string dummy; element *elementhash[128]; char name[128]; char keyword[128]; int Z, No; int verbose = 0; /* Namen einlesen */ ParseForParameter(verbose,file, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical); ParseForParameter(verbose,file, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical); ParseForParameter(verbose,file, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical); ParseForParameter(verbose,file,"ProcPEGamma", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical); ParseForParameter(verbose,file,"ProcPEPsi", 0, 1, 1, int_type, &(config::ProcPEPsi), 1, critical); if (!ParseForParameter(verbose,file,"Seed", 0, 1, 1, int_type, &(config::Seed), 1, optional)) config::Seed = 1; if(!ParseForParameter(verbose,file,"DoOutOrbitals", 0, 1, 1, int_type, &(config::DoOutOrbitals), 1, optional)) { config::DoOutOrbitals = 0; } else { if (config::DoOutOrbitals < 0) config::DoOutOrbitals = 0; if (config::DoOutOrbitals > 1) config::DoOutOrbitals = 1; } ParseForParameter(verbose,file,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical); if (config::DoOutVis < 0) config::DoOutVis = 0; if (config::DoOutVis > 1) config::DoOutVis = 1; if (!ParseForParameter(verbose,file,"VectorPlane", 0, 1, 1, int_type, &(config::VectorPlane), 1, optional)) config::VectorPlane = -1; if (!ParseForParameter(verbose,file,"VectorCut", 0, 1, 1, double_type, &(config::VectorCut), 1, optional)) config::VectorCut = 0.; ParseForParameter(verbose,file,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical); if (config::DoOutMes < 0) config::DoOutMes = 0; if (config::DoOutMes > 1) config::DoOutMes = 1; if (!ParseForParameter(verbose,file,"DoOutCurr", 0, 1, 1, int_type, &(config::DoOutCurrent), 1, optional)) config::DoOutCurrent = 0; if (config::DoOutCurrent < 0) config::DoOutCurrent = 0; if (config::DoOutCurrent > 1) config::DoOutCurrent = 1; ParseForParameter(verbose,file,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical); if (config::UseAddGramSch < 0) config::UseAddGramSch = 0; if (config::UseAddGramSch > 2) config::UseAddGramSch = 2; if(!ParseForParameter(verbose,file,"CommonWannier", 0, 1, 1, int_type, &(config::CommonWannier), 1, optional)) { config::CommonWannier = 0; } else { if (config::CommonWannier < 0) config::CommonWannier = 0; if (config::CommonWannier > 4) config::CommonWannier = 4; } if(!ParseForParameter(verbose,file,"SawtoothStart", 0, 1, 1, double_type, &(config::SawtoothStart), 1, optional)) { config::SawtoothStart = 0.01; } else { if (config::SawtoothStart < 0.) config::SawtoothStart = 0.; if (config::SawtoothStart > 1.) config::SawtoothStart = 1.; } ParseForParameter(verbose,file,"MaxOuterStep", 0, 1, 1, int_type, &(config::MaxOuterStep), 1, critical); ParseForParameter(verbose,file,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional); ParseForParameter(verbose,file,"OutVisStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional); ParseForParameter(verbose,file,"OutSrcStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional); ParseForParameter(verbose,file,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional); //ParseForParameter(verbose,file,"Thermostat", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional); if (!ParseForParameter(verbose,file,"EpsWannier", 0, 1, 1, double_type, &(config::EpsWannier), 1, optional)) config::EpsWannier = 1e-8; // stop conditions //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1; ParseForParameter(verbose,file,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical); if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3; ParseForParameter(verbose,file,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical); ParseForParameter(verbose,file,"RelEpsTotalE", 0, 1, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical); ParseForParameter(verbose,file,"RelEpsKineticE", 0, 1, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical); ParseForParameter(verbose,file,"MaxMinStopStep", 0, 1, 1, int_type, &(config::MaxMinStopStep), 1, critical); ParseForParameter(verbose,file,"MaxMinGapStopStep", 0, 1, 1, int_type, &(config::MaxMinGapStopStep), 1, critical); if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep; if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1; if (config::MaxMinGapStopStep < 1) config::MaxMinGapStopStep = 1; ParseForParameter(verbose,file,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical); ParseForParameter(verbose,file,"InitRelEpsTotalE", 0, 1, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical); ParseForParameter(verbose,file,"InitRelEpsKineticE", 0, 1, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical); ParseForParameter(verbose,file,"InitMaxMinStopStep", 0, 1, 1, int_type, &(config::InitMaxMinStopStep), 1, critical); ParseForParameter(verbose,file,"InitMaxMinGapStopStep", 0, 1, 1, int_type, &(config::InitMaxMinGapStopStep), 1, critical); if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep; if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1; if (config::InitMaxMinGapStopStep < 1) config::InitMaxMinGapStopStep = 1; // Unit cell and magnetic field ParseForParameter(verbose,file, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */ mol->cell_size[0] = BoxLength[0]; mol->cell_size[1] = BoxLength[3]; mol->cell_size[2] = BoxLength[4]; mol->cell_size[3] = BoxLength[6]; mol->cell_size[4] = BoxLength[7]; mol->cell_size[5] = BoxLength[8]; if (1) fprintf(stderr,"\n"); ParseForParameter(verbose,file,"DoPerturbation", 0, 1, 1, int_type, &(config::DoPerturbation), 1, optional); ParseForParameter(verbose,file,"DoOutNICS", 0, 1, 1, int_type, &(config::DoOutNICS), 1, optional); if (!ParseForParameter(verbose,file,"DoFullCurrent", 0, 1, 1, int_type, &(config::DoFullCurrent), 1, optional)) config::DoFullCurrent = 0; if (config::DoFullCurrent < 0) config::DoFullCurrent = 0; if (config::DoFullCurrent > 2) config::DoFullCurrent = 2; if (config::DoOutNICS < 0) config::DoOutNICS = 0; if (config::DoOutNICS > 2) config::DoOutNICS = 2; if (config::DoPerturbation == 0) { config::DoFullCurrent = 0; config::DoOutNICS = 0; } ParseForParameter(verbose,file,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical); ParseForParameter(verbose,file,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical); ParseForParameter(verbose,file,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical); if (config::Lev0Factor < 2) { config::Lev0Factor = 2; } ParseForParameter(verbose,file,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical); if (di >= 0 && di < 2) { config::RiemannTensor = di; } else { fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT"); exit(1); } switch (config::RiemannTensor) { case 0: //UseNoRT if (config::MaxLevel < 2) { config::MaxLevel = 2; } config::LevRFactor = 2; config::RTActualUse = 0; break; case 1: // UseRT if (config::MaxLevel < 3) { config::MaxLevel = 3; } ParseForParameter(verbose,file,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical); if (config::RiemannLevel < 2) { config::RiemannLevel = 2; } if (config::RiemannLevel > config::MaxLevel-1) { config::RiemannLevel = config::MaxLevel-1; } ParseForParameter(verbose,file,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical); if (config::LevRFactor < 2) { config::LevRFactor = 2; } config::Lev0Factor = 2; config::RTActualUse = 2; break; } ParseForParameter(verbose,file,"PsiType", 0, 1, 1, int_type, &di, 1, critical); if (di >= 0 && di < 2) { config::PsiType = di; } else { fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown"); exit(1); } switch (config::PsiType) { case 0: // SpinDouble ParseForParameter(verbose,file,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical); ParseForParameter(verbose,file,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional); break; case 1: // SpinUpDown if (config::ProcPEGamma % 2) config::ProcPEGamma*=2; ParseForParameter(verbose,file,"PsiMaxNoUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical); ParseForParameter(verbose,file,"PsiMaxNoDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical); ParseForParameter(verbose,file,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional); break; } // IonsInitRead ParseForParameter(verbose,file,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical); ParseForParameter(verbose,file,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical); ParseForParameter(verbose,file,"MaxTypes", 0, 1, 1, int_type, &(config::MaxTypes), 1, critical); if (!ParseForParameter(verbose,file,"RelativeCoord", 0, 1, 1, int_type, &(config::RelativeCoord) , 1, optional)) config::RelativeCoord = 0; if (!ParseForParameter(verbose,file,"StructOpt", 0, 1, 1, int_type, &(config::StructOpt), 1, optional)) config::StructOpt = 0; for (int i=0; i < config::MaxTypes; i++) { sprintf(name,"Ion_Type%i",i+1); ParseForParameter(verbose,file, (const char*)name, 0, 1, 1, int_type, &No, 1, critical); ParseForParameter(verbose,file, name, 0, 2, 1, int_type, &Z, 1, critical); elementhash[i] = periode->FindElement(Z); for(int j=0;jx.x[0], repetition, (repetition == 1) ? critical : optional) && ParseForParameter(verbose,file, keyword, 0, 2, 1, double_type, &neues->x.x[1], repetition, (repetition == 1) ? critical : optional) && ParseForParameter(verbose,file, keyword, 0, 3, 1, double_type, &neues->x.x[2], repetition, (repetition == 1) ? critical : optional)) repetition++; repetition--; cout << "Found " << repetition << " times of the keyword " << keyword << "." << endl; ParseForParameter(verbose,file, keyword, 0, 1, 1, double_type, &neues->x.x[0], repetition,critical); ParseForParameter(verbose,file, keyword, 0, 2, 1, double_type, &neues->x.x[1], repetition,critical); ParseForParameter(verbose,file, keyword, 0, 3, 1, double_type, &neues->x.x[2], repetition,critical); neues->type = elementhash[i]; // find element type mol->AddAtom(neues); } } }; /** Initializes config file structure by loading elements from a give file with old pcp syntax. * \param *file input file stream being the opened config file with old pcp syntax * \param *periode pointer to a periodentafel class with all elements * \param *mol pointer to molecule containing all atoms of the molecule */ void config::LoadOld(ifstream *file, periodentafel *periode, molecule *mol) { // ParseParameters /* Oeffne Hauptparameterdatei */ int l, i, di; double a,b; double BoxLength[9]; string zeile; string dummy; element *elementhash[128]; int Z, No, AtomNo, found; int verbose = 0; /* Namen einlesen */ ParseForParameter(verbose,file, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical); ParseForParameter(verbose,file, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical); ParseForParameter(verbose,file, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical); ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical); ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 2, 1, int_type, &(config::ProcPEPsi), 1, critical); config::Seed = 1; config::DoOutOrbitals = 0; ParseForParameter(verbose,file,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical); if (config::DoOutVis < 0) config::DoOutVis = 0; if (config::DoOutVis > 1) config::DoOutVis = 1; config::VectorPlane = -1; config::VectorCut = 0.; ParseForParameter(verbose,file,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical); if (config::DoOutMes < 0) config::DoOutMes = 0; if (config::DoOutMes > 1) config::DoOutMes = 1; config::DoOutCurrent = 0; ParseForParameter(verbose,file,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical); if (config::UseAddGramSch < 0) config::UseAddGramSch = 0; if (config::UseAddGramSch > 2) config::UseAddGramSch = 2; config::CommonWannier = 0; config::SawtoothStart = 0.01; ParseForParameter(verbose,file,"MaxOuterStep", 0, 1, 1, double_type, &(config::MaxOuterStep), 1, critical); ParseForParameter(verbose,file,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional); ParseForParameter(verbose,file,"VisOuterStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional); ParseForParameter(verbose,file,"VisSrcOuterStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional); ParseForParameter(verbose,file,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional); ParseForParameter(verbose,file,"ScaleTempStep", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional); config::EpsWannier = 1e-8; // stop conditions //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1; ParseForParameter(verbose,file,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical); if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3; ParseForParameter(verbose,file,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical); ParseForParameter(verbose,file,"MaxMinStep", 0, 2, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical); ParseForParameter(verbose,file,"MaxMinStep", 0, 3, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical); ParseForParameter(verbose,file,"MaxMinStep", 0, 4, 1, int_type, &(config::MaxMinStopStep), 1, critical); if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep; if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1; config::MaxMinGapStopStep = 1; ParseForParameter(verbose,file,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical); ParseForParameter(verbose,file,"MaxInitMinStep", 0, 2, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical); ParseForParameter(verbose,file,"MaxInitMinStep", 0, 3, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical); ParseForParameter(verbose,file,"MaxInitMinStep", 0, 4, 1, int_type, &(config::InitMaxMinStopStep), 1, critical); if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep; if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1; config::InitMaxMinGapStopStep = 1; ParseForParameter(verbose,file, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */ mol->cell_size[0] = BoxLength[0]; mol->cell_size[1] = BoxLength[3]; mol->cell_size[2] = BoxLength[4]; mol->cell_size[3] = BoxLength[6]; mol->cell_size[4] = BoxLength[7]; mol->cell_size[5] = BoxLength[8]; if (1) fprintf(stderr,"\n"); config::DoPerturbation = 0; config::DoFullCurrent = 0; ParseForParameter(verbose,file,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical); ParseForParameter(verbose,file,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical); ParseForParameter(verbose,file,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical); if (config::Lev0Factor < 2) { config::Lev0Factor = 2; } ParseForParameter(verbose,file,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical); if (di >= 0 && di < 2) { config::RiemannTensor = di; } else { fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT"); exit(1); } switch (config::RiemannTensor) { case 0: //UseNoRT if (config::MaxLevel < 2) { config::MaxLevel = 2; } config::LevRFactor = 2; config::RTActualUse = 0; break; case 1: // UseRT if (config::MaxLevel < 3) { config::MaxLevel = 3; } ParseForParameter(verbose,file,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical); if (config::RiemannLevel < 2) { config::RiemannLevel = 2; } if (config::RiemannLevel > config::MaxLevel-1) { config::RiemannLevel = config::MaxLevel-1; } ParseForParameter(verbose,file,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical); if (config::LevRFactor < 2) { config::LevRFactor = 2; } config::Lev0Factor = 2; config::RTActualUse = 2; break; } ParseForParameter(verbose,file,"PsiType", 0, 1, 1, int_type, &di, 1, critical); if (di >= 0 && di < 2) { config::PsiType = di; } else { fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown"); exit(1); } switch (config::PsiType) { case 0: // SpinDouble ParseForParameter(verbose,file,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical); config::AddPsis = 0; break; case 1: // SpinUpDown if (config::ProcPEGamma % 2) config::ProcPEGamma*=2; ParseForParameter(verbose,file,"MaxPsiUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical); ParseForParameter(verbose,file,"MaxPsiDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical); config::AddPsis = 0; break; } // IonsInitRead ParseForParameter(verbose,file,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical); ParseForParameter(verbose,file,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical); config::RelativeCoord = 0; config::StructOpt = 0; // Routine from builder.cpp for (i=0;i<128;i++) elementhash[i] = NULL; cout << Verbose(0) << "Parsing Ions ..." << endl; No=0; found = 0; while (getline(*file,zeile,'\n')) { if (zeile.find("Ions_Data") == 0) { cout << Verbose(1) << "found Ions_Data...begin parsing" << endl; found ++; } if (found > 0) { if (zeile.find("Ions_Data") == 0) getline(*file,zeile,'\n'); // read next line and parse this one istringstream input(zeile); input >> AtomNo; // number of atoms input >> Z; // atomic number input >> a; input >> l; input >> l; input >> b; // element mass elementhash[No] = periode->FindElement(Z); cout << Verbose(1) << "AtomNo: " << AtomNo << "\tZ: " << Z << "\ta:" << a << "\tl:" << l << "\b:" << b << "\tElement:" << elementhash[No] << "\t:" << endl; for(i=0;i> neues->x.x[0]; // x input2 >> neues->x.x[1]; // y input2 >> neues->x.x[2]; // z input2 >> l; neues->type = elementhash[No]; // find element type mol->AddAtom(neues); } No++; } } }; /** Stores all elements of config structure from which they can be re-read. * \param output open output *file stream to write to * \param *periode pointer to a periodentafel class with all elements * \param *mol pointer to molecule containing all atoms of the molecule */ bool config::Save(ofstream *output, periodentafel *periode, molecule *mol) const { bool result = true; // bring MaxTypes up to date mol->CountElements(); if (output != NULL) { *output << "# ParallelCarParinello - main configuration file - created with molecuilder" << endl; *output << endl; *output << "mainname\t" << config::mainname << "\t# programm name (for runtime files)" << endl; *output << "defaultpath\t" << config::defaultpath << "\t# where to put files during runtime" << endl; *output << "pseudopotpath\t" << config::pseudopotpath << "\t# where to find pseudopotentials" << endl; *output << endl; *output << "ProcPEGamma\t" << config::ProcPEGamma << "\t# for parallel computing: share constants" << endl; *output << "ProcPEPsi\t" << config::ProcPEPsi << "\t# for parallel computing: share wave functions" << endl; *output << "DoOutVis\t" << config::DoOutVis << "\t# Output data for OpenDX" << endl; *output << "DoOutMes\t" << config::DoOutMes << "\t# Output data for measurements" << endl; *output << "DoOutOrbitals\t" << config::DoOutOrbitals << "\t# Output all Orbitals" << endl; *output << "DoOutCurr\t" << config::DoOutCurrent << "\t# Ouput current density for OpenDx" << endl; *output << "DoOutNICS\t" << config::DoOutNICS << "\t# Output Nucleus independent current shieldings" << endl; *output << "DoPerturbation\t" << config::DoPerturbation << "\t# Do perturbation calculate and determine susceptibility and shielding" << endl; *output << "DoFullCurrent\t" << config::DoFullCurrent << "\t# Do full perturbation" << endl; *output << "CommonWannier\t" << config::CommonWannier << "\t# Put virtual centers at indivual orbits, all common, merged by variance, to grid point, to cell center" << endl; *output << "SawtoothStart\t" << config::SawtoothStart << "\t# Absolute value for smooth transition at cell border " << endl; *output << "VectorPlane\t" << config::VectorPlane << "\t# Cut plane axis (x, y or z: 0,1,2) for two-dim current vector plot" << endl; *output << "VectorCut\t" << config::VectorCut << "\t# Cut plane axis value" << endl; *output << "AddGramSch\t" << config::UseAddGramSch << "\t# Additional GramSchmidtOrtogonalization to be safe" << endl; *output << "Seed\t\t" << config::Seed << "\t# initial value for random seed for Psi coefficients" << endl; *output << endl; *output << "MaxOuterStep\t" << config::MaxOuterStep << "\t# number of MolecularDynamics/Structure optimization steps" << endl; *output << "Deltat\t" << config::Deltat << "\t# time per MD step" << endl; *output << "OutVisStep\t" << config::OutVisStep << "\t# Output visual data every ...th step" << endl; *output << "OutSrcStep\t" << config::OutSrcStep << "\t# Output \"restart\" data every ..th step" << endl; *output << "TargetTemp\t" << config::TargetTemp << "\t# Target temperature" << endl; *output << "MaxPsiStep\t" << config::MaxPsiStep << "\t# number of Minimisation steps per state (0 - default)" << endl; *output << "EpsWannier\t" << config::EpsWannier << "\t# tolerance value for spread minimisation of orbitals" << endl; *output << endl; *output << "# Values specifying when to stop" << endl; *output << "MaxMinStep\t" << config::MaxMinStep << "\t# Maximum number of steps" << endl; *output << "RelEpsTotalE\t" << config::RelEpsTotalEnergy << "\t# relative change in total energy" << endl; *output << "RelEpsKineticE\t" << config::RelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl; *output << "MaxMinStopStep\t" << config::MaxMinStopStep << "\t# check every ..th steps" << endl; *output << "MaxMinGapStopStep\t" << config::MaxMinGapStopStep << "\t# check every ..th steps" << endl; *output << endl; *output << "# Values specifying when to stop for INIT, otherwise same as above" << endl; *output << "MaxInitMinStep\t" << config::MaxInitMinStep << "\t# Maximum number of steps" << endl; *output << "InitRelEpsTotalE\t" << config::InitRelEpsTotalEnergy << "\t# relative change in total energy" << endl; *output << "InitRelEpsKineticE\t" << config::InitRelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl; *output << "InitMaxMinStopStep\t" << config::InitMaxMinStopStep << "\t# check every ..th steps" << endl; *output << "InitMaxMinGapStopStep\t" << config::InitMaxMinGapStopStep << "\t# check every ..th steps" << endl; *output << endl; *output << "BoxLength\t\t\t# (Length of a unit cell)" << endl; *output << mol->cell_size[0] << "\t" << endl; *output << mol->cell_size[1] << "\t" << mol->cell_size[2] << "\t" << endl; *output << mol->cell_size[3] << "\t" << mol->cell_size[4] << "\t" << mol->cell_size[5] << "\t" << endl; // FIXME *output << endl; *output << "ECut\t\t" << config::ECut << "\t# energy cutoff for discretization in Hartrees" << endl; *output << "MaxLevel\t" << config::MaxLevel << "\t# number of different levels in the code, >=2" << endl; *output << "Level0Factor\t" << config::Lev0Factor << "\t# factor by which node number increases from S to 0 level" << endl; *output << "RiemannTensor\t" << config::RiemannTensor << "\t# (Use metric)" << endl; switch (config::RiemannTensor) { case 0: //UseNoRT break; case 1: // UseRT *output << "RiemannLevel\t" << config::RiemannLevel << "\t# Number of Riemann Levels" << endl; *output << "LevRFactor\t" << config::LevRFactor << "\t# factor by which node number increases from 0 to R level from" << endl; break; } *output << "PsiType\t\t" << config::PsiType << "\t# 0 - doubly occupied, 1 - SpinUp,SpinDown" << endl; // write out both types for easier changing afterwards // switch (PsiType) { // case 0: *output << "MaxPsiDouble\t" << config::MaxPsiDouble << "\t# here: specifying both maximum number of SpinUp- and -Down-states" << endl; // break; // case 1: *output << "PsiMaxNoUp\t" << config::PsiMaxNoUp << "\t# here: specifying maximum number of SpinUp-states" << endl; *output << "PsiMaxNoDown\t" << config::PsiMaxNoDown << "\t# here: specifying maximum number of SpinDown-states" << endl; // break; // } *output << "AddPsis\t\t" << config::AddPsis << "\t# Additional unoccupied Psis for bandgap determination" << endl; *output << endl; *output << "RCut\t\t" << config::RCut << "\t# R-cut for the ewald summation" << endl; *output << "StructOpt\t" << config::StructOpt << "\t# Do structure optimization beforehand" << endl; *output << "IsAngstroem\t" << config::IsAngstroem << "\t# 0 - Bohr, 1 - Angstroem" << endl; *output << "RelativeCoord\t" << config::RelativeCoord << "\t# whether ion coordinates are relative (1) or absolute (0)" << endl; *output << "MaxTypes\t" << mol->ElementCount << "\t# maximum number of different ion types" << endl; *output << endl; result = result && mol->Checkout(output); result = result && mol->Output(output); return result; } else return false; }; /** Reads parameter from a parsed file. * The file is either parsed for a certain keyword or if null is given for * the value in row yth and column xth. If the keyword was necessity#critical, * then an error is thrown and the programme aborted. * \warning value is modified (both in contents and position)! * \param verbose 1 - print found value to stderr, 0 - don't * \param file file to be parsed * \param name Name of value in file (at least 3 chars!) * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning * (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read - * best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now * counted from this unresetted position!) * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!) * \param yth In grid case specifying column number, otherwise the yth \a name matching line * \param type Type of the Parameter to be read * \param value address of the value to be read (must have been allocated) * \param repetition determines, if the keyword appears multiply in the config file, which repetition shall be parsed, i.e. 1 if not multiply * \param critical necessity of this keyword being specified (optional, critical) * \return 1 - found, 0 - not found * \note Routine is taken from the pcp project and hack-a-slack adapted to C++ */ int config::ParseForParameter(int verbose, ifstream *file, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical) { int i,j; // loop variables int length = 0, maxlength = -1; long file_position = file->tellg(); // mark current position char *dummy1, *dummy, *free_dummy; // pointers in the line that is read in per step dummy1 = free_dummy = (char *) Malloc(256 * sizeof(char), "config::ParseForParameter: *free_dummy"); //fprintf(stderr,"Parsing for %s\n",name); if (repetition == 0) //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!"); return 0; int line = 0; // marks line where parameter was found int found = (type >= grid) ? 0 : (-yth + 1); // marks if yth parameter name was found while((found != repetition)) { dummy1 = dummy = free_dummy; do { file->getline(dummy1, 256); // Read the whole line if (file->eof()) { if ((critical) && (found == 0)) { Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy"); //Error(InitReading, name); fprintf(stderr,"Error:InitReading, critical %s not found\n", name); exit(255); } else { //if (!sequential) file->clear(); file->seekg(file_position, ios::beg); // rewind to start position Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy"); return 0; } } line++; } while (((dummy1[0] == '#') || (dummy1[0] == '\n')) && dummy != NULL); // skip commentary and empty lines // C++ getline removes newline at end, thus re-add if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) { i = strlen(dummy1); dummy1[i] = '\n'; dummy1[i+1] = '\0'; } //fprintf(stderr,"line ends at %i, newline at %i\n", strlen(dummy1), strchr(dummy1,'\n')-free_dummy); if (dummy1 == NULL) { if (verbose) fprintf(stderr,"Error reading line %i\n",line); } else { //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1); } // Seek for possible end of keyword on line if given ... if (name != NULL) { dummy = strchr(dummy1,'\t'); // set dummy on first tab or space which ever's nearer if (dummy == NULL) { dummy = strchr(dummy1, ' '); // if not found seek for space while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary dummy++; } if (dummy == NULL) { dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword) //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name); //Free((void **)&free_dummy); //Error(FileOpenParams, NULL); } else { //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1); } } else dummy = dummy1; // ... and check if it is the keyword! //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name)); if ((name == NULL) || ((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name))) { found++; // found the parameter! //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy); if (found == repetition) { for (i=0;i= grid) { // grid structure means that grid starts on the next line, not right after keyword dummy1 = dummy = free_dummy; do { file->getline(dummy1, 256); // Read the whole line, skip commentary and empty ones if (file->eof()) { if ((critical) && (found == 0)) { Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy"); //Error(InitReading, name); fprintf(stderr,"Error:InitReading, critical %s not found\n", name); exit(255); } else { //if (!sequential) file->clear(); file->seekg(file_position, ios::beg); // rewind to start position Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy"); return 0; } } line++; } while ((dummy1[0] == '#') || (dummy1[0] == '\n')); if (dummy1 == NULL){ if (verbose) fprintf(stderr,"Error reading line %i\n", line); } else { //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1); } } else { // simple int, strings or doubles start in the same line while ((*dummy == '\t') || (*dummy == ' ')) // skip interjacent tabs and spaces dummy++; } // C++ getline removes newline at end, thus re-add if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) { j = strlen(dummy1); dummy1[j] = '\n'; dummy1[j+1] = '\0'; } int start = (type >= grid) ? 0 : yth-1 ; for (j=start;j j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) { *((double *)value) = 0.0; fprintf(stderr,"%f\t",*((double *)value)); value = (void *)((long)value + sizeof(double)); //value += sizeof(double); } else { // otherwise we must skip all interjacent tabs and spaces and find next value dummy1 = dummy; dummy = strchr(dummy1, '\t'); // seek for tab or space if (dummy == NULL) { dummy = strchr(dummy1, ' '); // if not found seek for space while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary dummy++; } /* while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary dummy++;*/ if (dummy == NULL) { // if still zero returned ... dummy = strchr(dummy1, '\n'); // ... at line end then if ((j < yth-1) && (type < 4)) { // check if xth value or not yet if (critical) { if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name); Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy"); //return 0; exit(255); //Error(FileOpenParams, NULL); } else { //if (!sequential) file->clear(); file->seekg(file_position, ios::beg); // rewind to start position Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy"); return 0; } } } else { //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy); } //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy); switch(type) { case (row_int): *((int *)value) = atoi(dummy1); if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name); if (verbose) fprintf(stderr,"%i\t",*((int *)value)); value = (void *)((long)value + sizeof(int)); //value += sizeof(int); break; case(row_double): case(grid): case(lower_trigrid): case(upper_trigrid): *((double *)value) = atof(dummy1); if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name); if (verbose) fprintf(stderr,"%lg\t",*((double *)value)); value = (void *)((long)value + sizeof(double)); //value += sizeof(double); break; case(double_type): *((double *)value) = atof(dummy1); if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value)); //value += sizeof(double); break; case(int_type): *((int *)value) = atoi(dummy1); if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value)); //value += sizeof(int); break; default: case(string_type): if (value != NULL) { if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum strncpy((char *)value, dummy1, length); // copy as much ((char *)value)[length] = '\0'; // and set end marker if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length); //value += sizeof(char); } else { } break; } } while (*dummy == '\t') dummy++; } } } } } if ((type >= row_int) && (verbose)) fprintf(stderr,"\n"); Free((void **)&free_dummy, "config::ParseForParameter: *free_dummy"); if (!sequential) { file->clear(); file->seekg(file_position, ios::beg); // rewind to start position } //fprintf(stderr, "End of Parsing\n\n"); return (found); // true if found, false if not }