Hex  2.2
Hydrogen-electron collision solver
io.h
Go to the documentation of this file.
1 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
2 // //
3 // / / / / __ \ \ / / //
4 // / /__ / / / _ \ \ \/ / //
5 // / ___ / | |/_/ / /\ \ //
6 // / / / / \_\ / / \ \ //
7 // //
8 // //
9 // Copyright (c) 2016, Jakub Benda, Charles University in Prague //
10 // //
11 // MIT License: //
12 // //
13 // Permission is hereby granted, free of charge, to any person obtaining a //
14 // copy of this software and associated documentation files (the "Software"), //
15 // to deal in the Software without restriction, including without limitation //
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense, //
17 // and/or sell copies of the Software, and to permit persons to whom the //
18 // Software is furnished to do so, subject to the following conditions: //
19 // //
20 // The above copyright notice and this permission notice shall be included //
21 // in all copies or substantial portions of the Software. //
22 // //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS //
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE //
26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, //
27 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF //
28 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. //
29 // //
30 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
31 
32 #ifndef HEX_IO_H
33 #define HEX_IO_H
34 
35 #include <cstdio>
36 #include <fstream>
37 #include <vector>
38 #include <string>
39 
40 #include "hex-arrays.h"
41 
42 #include "bspline.h"
43 #include "luft.h"
44 #include "parallel.h"
45 
58 {
59  public:
60 
74  typedef enum {
76  StgNone = 0x00,
78  StgRadial = 0x01,
80  StgSolve = 0x02,
82  StgExtract = 0x04
83  } HexEcsStg;
84 
85  // constructor
86  CommandLine (int argc, char* argv[])
87  : writegrid(false), zipdata(), parallel(false), preconditioner("ILU"),
88  droptol(1e-8), itinerary(StgNone), outofcore(false), cont(false), wholematrix(false), cache_all_radint(true), cache_own_radint(true),
89  itertol(1e-8), prec_itertol(1e-8), parallel_precondition(false), gpu_large_data(false),
91  kpa_simple_rad(false), ocl_platform(0), ocl_device(0), factorizer("umfpack"), groupsize(1),
97  dom_preconditioner("ILU"), dom_sweeps(-1), scratch(std::getenv("SCRATCHDIR") ? std::getenv("SCRATCHDIR") : "."), analytic_eigenstates(false),
99  {
100  // get command line options
101  parse(argc, argv);
102 
103  // run the whole sequence if nothing specified
104  if (itinerary == StgNone)
106  }
107 
109  void parse (int argc, char* argv[]);
110 
111  //
112  // public attributes
113  //
114 
116  std::ifstream inputfile;
117 
118  // Write grid layout to a VTK file.
119  bool writegrid;
120 
122  struct s_zipdata
123  {
124  // default constructor
125  s_zipdata () : file(), Xmin(-1), Ymin(-1), Xmax(-1), Ymax(-1), nX(-1), nY(-1) {}
126 
127  std::string file;
128  Real Xmin, Ymin, Xmax, Ymax;
129  int nX, nY;
130  }
131  zipdata;
132 
134  bool parallel;
135 
137  std::string preconditioner;
138 
140  Real droptol;
141 
144 
146  bool outofcore;
147 
149  bool cont;
150 
153 
157 
159  Real itertol;
160 
163 
166 
169 
172 
175 
178 
181 
183  unsigned ocl_platform;
184 
186  unsigned ocl_device;
187 
189  std::string factorizer;
190 
193 
196 
199 
202 
205 
208 
211 
214 
217 
220 
223 
226 
229 
231  std::vector<std::string> map_solution;
232 
234  std::string map_solution_target;
235 
237  Real ssor;
238 
241 
244 
247 
250 
253 
255  Real kpa_drop;
256 
259 
262 
265 
268 
271 
274 
276  std::string dom_preconditioner;
277 
280 
282  std::string scratch;
283 
286 
289 
292 };
293 
322 {
323  public:
324 
325  // constructor
326  InputFile (std::ifstream & inputfile)
327  {
328  // read inputfile
329  read(inputfile);
330 
331  // maximal angular momentum (the same for both parities)
332  maxell = levels + L;
333  }
334 
335  // read data from file
336  void read (std::ifstream & inputfile);
337 
338  //
339  // public attributes
340  //
341 
342  // B-spline order
343  int order;
344 
345  // initial atomic principal quantum number
346  int ni;
347 
348  // total angular momentum
349  int L;
350 
351  // total parity
352  int Pi;
353 
354  // 'nL', the limit on number of coupled angular states;
355  // there will be 'nL * (L + 1 - Pi)' coupled angular state pairs
356  int levels;
357 
358  // upper limit on the smaller of the one-electron angular momenta
359  int limit;
360 
361  // maximal one-electron orbital quantum number
362  int maxell;
363 
364  // total spins to calculate
365  iArray Spin;
366 
367  // ECS rotation angle
368  Real ecstheta;
369 
370  // weak magnetic field in atomic units (involved only perturbatively)
371  Real B;
372 
373  // maximal energy (Ry) of states included in the asymptotic (outer) region
375 
376  // real B-spline knots
377  rArray rknots;
378 
379  // real B-spline knot projectile extention
380  rArray rknots_ext;
381 
382  // complex-to-become knots (after rotation)
383  rArray cknots;
384 
385  // total energies for which to solve the system
386  rArray Etot;
387 
388  // maximal total energy
389  Real max_Etot;
390 
391  // initial and final atomic states
392  std::vector<std::tuple<int,int,int>> instates, outstates;
393 
394  // atom charge (must be positive integer)
395  Real Za;
396 
397  // projectile charge (only sign)
398  Real Zp;
399 
400  // whether to calculate just the inner problem (decided from the knot sequence)
402 
403  // keep only l1 <= l2; this is useful for large total angular momenta for reduction of the angular basis
404  bool exchange;
405 };
406 
415 {
416  public:
417 
419 
420  SolutionIO
421  (
422  int L, int S, int Pi,
423  int ni, int li, int mi,
424  Real E,
425  std::vector<std::pair<int,int>> const & ang,
426  std::vector<std::pair<int,int>> const & chann = std::vector<std::pair<int,int>>(),
427  std::string prefix = "psi"
428  ) : L_(L), S_(S), Pi_(Pi),
429  ni_(ni), li_(li), mi_(mi),
430  E_(E), ang_(ang), prefix_(prefix)
431  {
432  if (chann.empty())
433  {
434  // initialize channel counts to zero
435  chann_.resize(ang.size(), std::make_pair(0,0));
436  }
437  else
438  {
439  // check consistency of the parameters
440  if (ang.size() != chann.size())
441  HexException("Incompatible size of angular momentum pairs list and channel count list.");
442 
443  // use the supplied channel counts
444  chann_ = chann;
445  }
446  }
447 
449  static const int All = -1;
450 
452  std::string name (int ill = SolutionIO::All) const
453  {
454  if (ill == -1)
455  return format("%s-%g-%d-%d-%d-%d-%d-%d.hdf", prefix_.c_str(), E_ + 1, L_, S_, Pi_, ni_, li_, mi_);
456  else
457  return format("%s-%g-%d-%d-%d-%d-%d-%d-(%d,%d).hdf", prefix_.c_str(), E_ + 1, L_, S_, Pi_, ni_, li_, mi_, ang_[ill].first, ang_[ill].second);
458  }
459 
461  bool check (int ill, std::size_t & total_size) const
462  {
463  // look for specific solution segment file
464  if (ill != SolutionIO::All)
465  {
466  HDFFile fsingle (name(ill), HDFFile::readonly);
467  return fsingle.valid() ? fsingle.size("array")/2 : 0;
468  }
469 
470  // look for all solution segment files
471  std::vector<std::size_t> size (ang_.size());
472  for (unsigned illp = 0; illp < ang_.size(); illp++)
473  {
474  HDFFile fsingle (name(illp), HDFFile::readonly);
475  size[illp] = (fsingle.valid() ? fsingle.size("array")/2 : 0);
476  }
477 
478  // calculate total size
479  total_size = std::accumulate(size.begin(), size.end(), 0);
480 
481  // check that all blocks existed
482  return std::find(size.begin(), size.end(), 0) == size.end();
483  }
484  bool check (int ill = SolutionIO::All) const
485  {
486  std::size_t total_size = 0;
487  return check(ill, total_size);
488  }
489 
498  bool load (BlockArray<Complex> & solution, int ill = SolutionIO::All)
499  {
500  // check that the requested files are present
501  if (not check(ill))
502  return false;
503 
504  // select segments
505  iArray segments_to_load = { ill };
506  if (ill == SolutionIO::All)
507  segments_to_load = linspace<int>(0, solution.size() - 1, solution.size());
508 
509  // for all blocks to load
510  for (int i : segments_to_load)
511  {
512  //
513  // Either read from the whole monolithic solution file ...
514  //
515 
516  HDFFile hdf (name(), HDFFile::readonly);
517  if (hdf.valid())
518  {
519  // get segment size
520  std::size_t segsize = hdf.size("array") / ang_.size();
521 
522  // allocate memory
523  solution[i].resize(segsize);
524 
525  // read data from the file
526  if (not hdf.read("array", solution[i].data(), segsize, i * segsize))
527  return false;
528 
529  // dump to disk
530  if (not solution.inmemory())
531  {
532  solution.hdfsave(i);
533  solution[i].drop();
534  }
535  }
536 
537  //
538  // ... or read from a solution segment.
539  //
540 
541  else
542  {
543  // simply load the requested solution segment file
544  if (not solution[i].hdfload(name(i)))
545  return false;
546 
547  // dump to disk
548  if (not solution.inmemory())
549  {
550  solution.hdfsave(i);
551  solution[i].drop();
552  }
553 
554  // read numbers of channels
555  HDFFile hdf (name(i), HDFFile::readonly);
556  if (hdf.valid())
557  {
558  hdf.read("Nchan1", &chann_[i].first, 1);
559  hdf.read("Nchan2", &chann_[i].second, 1);
560  }
561  }
562  }
563 
564  return true;
565  }
566 
575  bool save (BlockArray<Complex> const & solution, int ill = SolutionIO::All) const
576  {
577  // select segments
578  iArray segments_to_save = { ill };
579  if (ill == SolutionIO::All)
580  segments_to_save = linspace<int>(0, solution.size() - 1, solution.size());
581 
582  // for all segments
583  for (int iseg : segments_to_save)
584  {
585  // load data
586  if (not solution.inmemory())
587  const_cast<BlockArray<Complex>&>(solution).hdfload(iseg);
588 
589  // write data
590  if (not save_segment(solution[iseg], iseg))
591  return false;
592 
593  // unload data
594  if (not solution.inmemory())
595  const_cast<BlockArray<Complex>&>(solution)[iseg].drop();
596  }
597 
598  // success
599  return true;
600  }
601 
602  bool save_segment (const cArrayView solution, int ill) const
603  {
604  // open file
605  HDFFile hdf (name(ill), HDFFile::overwrite);
606 
607  // check file status
608  if (not hdf.valid())
609  return false;
610 
611  // write data
612  bool success = true;
613  success = (success and hdf.write("L", &L_, 1));
614  success = (success and hdf.write("S", &S_, 1));
615  success = (success and hdf.write("Pi", &Pi_, 1));
616  success = (success and hdf.write("ni", &ni_, 1));
617  success = (success and hdf.write("li", &li_, 1));
618  success = (success and hdf.write("mi", &mi_, 1));
619  success = (success and hdf.write("E", &E_, 1));
620  success = (success and hdf.write("l1", &ang_[ill].first, 1));
621  success = (success and hdf.write("l2", &ang_[ill].second, 1));
622  success = (success and hdf.write("Nchan1", &chann_[ill].first, 1));
623  success = (success and hdf.write("Nchan2", &chann_[ill].second, 1));
624  success = (success and hdf.write("array", solution.data(), solution.size()));
625  return success;
626  }
627 
628  std::vector<std::pair<int,int>> const & channels () const { return chann_; }
629 
630  private:
631 
632  int L_, S_, Pi_, ni_, li_, mi_;
633  Real E_;
634  std::vector<std::pair<int,int>> ang_, chann_;
635  std::string prefix_;
636 };
637 
655 void zip_solution
656 (
657  CommandLine const & cmd,
658  InputFile const & inp,
659  Parallel const & par,
660  Bspline const & bspline_inner,
661  Bspline const & bspline_full,
662  std::vector<std::pair<int,int>> const & ll
663 );
664 
668 void write_grid
669 (
670  Bspline const & bspline,
671  std::string const & basename
672 );
673 
674 #endif /* HEX_IO_H */
bool check(int ill, std::size_t &total_size) const
Check that the file exists.
Definition: io.h:461
Real prec_itertol
Tolerance for terminating block preconditioner.
Definition: io.h:162
bool extract_extrapolate
Whether to radially extrapolate the extracted T-matrix.
Definition: io.h:216
void zip_solution(CommandLine const &cmd, InputFile const &inp, Parallel const &par, Bspline const &bspline_inner, Bspline const &bspline_full, std::vector< std::pair< int, int >> const &ll)
Convert solution to VTK file.
Definition: io.cpp:1107
int max_sub_iter
Maximal number of sub-preconditioner iterations.
Definition: io.h:204
bool analytic_eigenstates
Use analytic eigenstates instead of those obtained by diagonalization.
Definition: io.h:285
bool parallel
Whether to use MPI.
Definition: io.h:134
int Pi
Definition: io.h:352
bool outofcore
Whether to keep precomputed data only on disk and spare RAM.
Definition: io.h:146
Real ssor
Apply SSOR coupling.
Definition: io.h:237
void write_grid(Bspline const &bspline, std::string const &basename)
Write grid to a VTK file.
Definition: io.cpp:1307
CommandLine(int argc, char *argv[])
Definition: io.h:86
int dom_y_panels
Definition: io.h:273
std::string dom_preconditioner
Domain preconditioner.
Definition: io.h:276
bool cont
Whether to continue out-of-core computation from last computed solution (needs corresponding ooc file...
Definition: io.h:149
bool cache_all_radint
Whether to keep radial integrals in memory.
Definition: io.h:155
int hyb_additional_levels
Additional levels to be solved by ILU preconditioner when using HYB preconditioner.
Definition: io.h:264
bool carry_initial_guess
Whether to use previous-energy solution as an initial guess.
Definition: io.h:210
Extract the T-matrices.
Definition: io.h:82
int itinerary
Which parts of the computation to run.
Definition: io.h:143
A B-spline expansion of a solution to "zip". See Bspline::zip .
Definition: io.h:122
bool inner_only
Definition: io.h:401
bool mumps_outofcore
MUMPS out of core.
Definition: io.h:249
int parallel_factorization
Allow parallel factorization.
Definition: io.h:195
B-spline environment.
Definition: bspline.h:57
int nY
Definition: io.h:129
Real ecstheta
Definition: io.h:368
int nX
Definition: io.h:129
std::string scratch
Scratch directory for out-of-core data.
Definition: io.h:282
bool refine_solution
Load also existing solutions and check that they are within tolerance.
Definition: io.h:228
int groupsize
Size of the local MPI communicator, used for distributed SuperLU.
Definition: io.h:192
Real Ymax
Definition: io.h:128
std::string preconditioner
Preconditioner to use.
Definition: io.h:137
std::string factorizer
LU-factorizer.
Definition: io.h:189
bool save(BlockArray< Complex > const &solution, int ill=SolutionIO::All) const
Write solution to disk.
Definition: io.h:575
bool fail_on_sub_iter
Stop with error message when sub-preconditioner fails to converge.
Definition: io.h:207
bool write_intermediate_solutions
Write intermediate solutions.
Definition: io.h:258
iArray Spin
Definition: io.h:365
int extract_samples
Extraction averaging/extrapolation sample count.
Definition: io.h:225
Solution input/output class.
Definition: io.h:414
std::string map_solution_target
Target mapping basis.
Definition: io.h:234
static const int All
All blocks flag.
Definition: io.h:449
Real itertol
Tolerance for terminating iterative solution.
Definition: io.h:159
bool lightweight_radial_cache
Definition: io.h:171
bool kpa_simple_rad
Use simplified radial integral matrix for nested KPA iterations (experimental).
Definition: io.h:180
Real Za
Definition: io.h:395
bool gpu_host_multiply
Keep vectors in host memory when doing multiplication on GPU.
Definition: io.h:246
Command line parameters.
Definition: io.h:57
struct CommandLine::s_zipdata zipdata
bool exchange
Definition: io.h:404
std::vector< std::pair< int, int > > const & channels() const
Definition: io.h:628
bool fast_bessel
Use faster Bessel function evaluation routine (not the Steed/Barnett) when calculating RHS...
Definition: io.h:261
s_zipdata()
Definition: io.h:125
bool gpu_multiply
Do the sparse matrix multiplication on the OpenCL device (memory intensive!).
Definition: io.h:213
int maxell
Definition: io.h:362
int mumps_verbose
MUMPS diagnostic information.
Definition: io.h:252
unsigned ocl_device
Index of OpenCL device to use.
Definition: io.h:186
int ni
Definition: io.h:346
rArray rknots_ext
Definition: io.h:380
unsigned ocl_platform
Index of OpenCL platform to use.
Definition: io.h:183
Solve the equations.
Definition: io.h:80
bool noluupdate
Keep calculated LU also for next energy.
Definition: io.h:240
bool reuse_dia_blocks
Whether to use diagonal blocks as present in the scratch directory. (For debugging purposes only...
Definition: io.h:177
Compute only the radial integrals necessary for the construction of the equations.
Definition: io.h:78
bool runtime_postprocess
Calculate T-matrices after every iteration.
Definition: io.h:288
Real channel_max_E
Definition: io.h:374
Real extract_rho
Extraction radius.
Definition: io.h:219
bool gpu_large_data
Keep large data in RAM instead of copying to the OpenCL compute device.
Definition: io.h:168
std::string file
Definition: io.h:127
InputFile(std::ifstream &inputfile)
Definition: io.h:326
Input parameters.
Definition: io.h:321
void parse(int argc, char *argv[])
Read options from command line.
Definition: io.cpp:145
Real max_Etot
Definition: io.h:389
bool writegrid
Definition: io.h:119
rArray cknots
Definition: io.h:383
std::string name(int ill=SolutionIO::All) const
Get name of the solution file.
Definition: io.h:452
int order
Definition: io.h:343
HexEcsStg
Stages of the computations.
Definition: io.h:74
int levels
Definition: io.h:356
bool lightweight_full
Whether to avoid explicitly calculating big matrices and only apply them on the fly.
Definition: io.h:171
MPI info.
Definition: parallel.h:50
std::vector< std::string > map_solution
Map solution between different B-spline bases.
Definition: io.h:231
rArray Etot
Definition: io.h:386
int L
Definition: io.h:349
bool save_segment(const cArrayView solution, int ill) const
Definition: io.h:602
SolutionIO()
Definition: io.h:418
Real extract_rho_begin
Radial distance where to start radial averaging/extrapolation of the T-matrix.
Definition: io.h:222
std::vector< std::tuple< int, int, int > > outstates
Definition: io.h:392
bool wholematrix
Whether to load full matrix from scratch disk at once when calculating dot product (and not by parts)...
Definition: io.h:152
Real Zp
Definition: io.h:398
bool check(int ill=SolutionIO::All) const
Definition: io.h:484
int limit
Definition: io.h:359
int multigrid_depth
Depth of the geometric multigrid.
Definition: io.h:267
bool load(BlockArray< Complex > &solution, int ill=SolutionIO::All)
Load the solution from disk.
Definition: io.h:498
int coupling_limit
Maximal multipole considered by the coupled preconditioner.
Definition: io.h:243
Real Ymin
Definition: io.h:128
Do not start any intensive computations.
Definition: io.h:76
int multigrid_coarse_prec
What preconditioner to use for solution of the coarse problem.
Definition: io.h:270
bool shared_scratch
Whether to compute only a subset of radial integrals in shared scratch architecture.
Definition: io.h:174
int ilu_max_iter
Maximal number of ILU iterations for hybrid preconditioner.
Definition: io.h:201
Real B
Definition: io.h:371
Real Xmin
Definition: io.h:128
bool cache_own_radint
Definition: io.h:156
int dom_sweeps
Domain decomposition sweeps.
Definition: io.h:279
Real Xmax
Definition: io.h:128
bool parallel_precondition
Whether to use OpenMP parallelization to run preconditioner for several blocks simultaneously.
Definition: io.h:165
Real droptol
Drop tolerance for the ILU preconditioner.
Definition: io.h:140
std::ifstream inputfile
Alternative name for the input file. Default is "hex.inp".
Definition: io.h:116
int dom_x_panels
Domain decomposition panels.
Definition: io.h:273
Real kpa_drop
Whether to use drop tolerance for KPA preconditioner.
Definition: io.h:255
bool sub_prec_verbose
Verbosity of the sub-preconditioner.
Definition: io.h:291
int parallel_extraction
Allow parallel extraction.
Definition: io.h:198
rArray rknots
Definition: io.h:377