TBTK
Need a break? Support the development by playing Polarity Puzzles
PropertyExtractor.h
Go to the documentation of this file.
1 /* Copyright 2016 Kristofer Björnson
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
23 #ifndef COM_DAFER45_TBTK_PROPERTY_EXTRACTOR_PROPERTY_EXTRACTOR
24 #define COM_DAFER45_TBTK_PROPERTY_EXTRACTOR_PROPERTY_EXTRACTOR
25 
27 #include "TBTK/Index.h"
28 #include "TBTK/Property/AbstractProperty.h"
29 #include "TBTK/Property/Density.h"
30 #include "TBTK/Property/DOS.h"
31 #include "TBTK/Property/LDOS.h"
34 #include "TBTK/Solver/Solver.h"
35 
36 #include <complex>
37 //#include <initializer_list>
38 
39 namespace TBTK{
40 namespace PropertyExtractor{
41 
65 public:
68 
70  virtual ~PropertyExtractor();
71 
79  virtual void setEnergyWindow(
80  double lowerBound,
81  double upperBound,
82  int energyResolution
83  );
84 
99  virtual void setEnergyWindow(
100  int lowerFermionicMatsubaraEnergyIndex,
101  int upperFermionicMatsubaraEnergyIndex,
102  int lowerBosonicMatsubaraEnergyIndex,
103  int upperBosonicMatsubaraEnergyIndex
104  );
105 
112  virtual void setEnergyInfinitesimal(double energyInfinitesimal);
113 
141  Index pattern,
142  Index ranges
143  );
144 
157  std::vector<Index> patterns
158  );
159 
197  Index pattern,
198  Index ranges
199  );
200 
213  std::vector<Index> patterns
214  );
215 
242  virtual Property::LDOS calculateLDOS(Index pattern, Index ranges);
243 
258  std::vector<Index> patterns
259  );
260 
305  Index pattern,
306  Index ranges
307  );
308 
323  std::vector<Index> patterns
324  );
325 
337  virtual std::complex<double> calculateExpectationValue(
338  Index to,
339  Index from
340  );
341 
348  virtual Property::DOS calculateDOS();
349 
363  virtual Property::DOS sampleDOS(
364  unsigned int numSamples,
365  const std::vector<Index> &patterns = {},
366  unsigned int seed = time(nullptr)
367  );
368 
375  virtual double calculateEntropy();
376 protected:
378  enum class EnergyType{Real, Matsubara};
379 
383  EnergyType getEnergyType() const;
384 
388  int getEnergyResolution() const;
389 
393  double getLowerBound() const;
394 
398  double getUpperBound() const;
399 
404 
409 
414 
419 
424  class Information{
425  public:
428  Information();
429 
433  void setSpinIndex(int spinIndex);
434 
439  int getSpinIndex() const;
440  private:
442  int spinIndex;
443  };
444 
445  /*** Get the nergy infinitesimal.
446  *
447  * @return The energy infinitesimal. */
448  double getEnergyInfinitesimal() const;
449 
493  template<typename DataType>
494  void calculate(
495  void (*callback)(
496  PropertyExtractor *cb_this,
497  Property::Property &property,
498  const Index &index,
499  int offset,
500  Information &information
501  ),
503  Index pattern,
504  const Index &ranges,
505  int currentOffset,
506  int offsetMultiplier,
507  Information &information
508  );
509 
524  template<typename DataType>
525  void calculate(
526  void (*callback)(
527  PropertyExtractor *cb_this,
528  Property::Property &property,
529  const Index &index,
530  int offset,
531  Information &information
532  ),
533  const IndexTree &allIndices,
534  const IndexTree &memoryLayout,
535  Property::AbstractProperty<DataType> &abstractProperty,
536  Information &information
537  );
538 
545  void ensureCompliantRanges(const Index &pattern, Index &ranges);
546 
559  std::vector<int> getLoopRanges(
560  const Index &pattern,
561  const Index &ranges
562  );
563 
586  std::vector<Index> patterns,
587  const HoppingAmplitudeSet &hoppingAmplitudeSet,
588  bool keepSummationWildcards,
589  bool keepSpinWildcards
590  );
591 private:
593  EnergyType energyType;
594 
596  static constexpr int ENERGY_RESOLUTION = 1000;
597 
600  int energyResolution;
601 
603  static constexpr double LOWER_BOUND = -1.;
604 
607  double lowerBound;
608 
610  static constexpr double UPPER_BOUND = 1.;
611 
614  double upperBound;
615 
617  static constexpr int LOWER_FERMIONIC_MATSUBARA_ENERGY_INDEX = -1;
618 
621  int lowerFermionicMatsubaraEnergyIndex;
622 
624  static constexpr int UPPER_FERMIONIC_MATSUBARA_ENERGY_INDEX = 1;
625 
628  int upperFermionicMatsubaraEnergyIndex;
629 
631  static constexpr int LOWER_BOSONIC_MATSUBARA_ENERGY_INDEX = 0;
632 
635  int lowerBosonicMatsubaraEnergyIndex;
636 
638  static constexpr int UPPER_BOSONIC_MATSUBARA_ENERGY_INDEX = 0;
639 
642  int upperBosonicMatsubaraEnergyIndex;
643 
645  static constexpr double ENERGY_INFINITESIMAL = 1e-3;
646 
649  double energyInfinitesimal;
650 
652  virtual const Solver::Solver& getSolver() const;
653 };
654 
656  return energyType;
657 }
658 
660  TBTKAssert(
661  energyType == EnergyType::Real,
662  "PropertyExtractor::PropertyExtractor::getEnergyResolution()",
663  "The energy resolution cannot be accessed when the energy type"
664  << " is Matsubara.",
665  "Use PropertyExtractor::PropertyExtractor::setEnergyWindow()"
666  << " with three arguments if real energies are wanted for the"
667  << " PropertyExtractor."
668  );
669 
670  return energyResolution;
671 }
672 
673 inline double PropertyExtractor::getLowerBound() const{
674  TBTKAssert(
675  energyType == EnergyType::Real,
676  "PropertyExtractor::PropertyExtractor::getLowerBound()",
677  "The lower bound cannot be accessed when the energy type is"
678  << " Matsubara.",
679  "Use PropertyExtractor::PropertyExtractor::setEnergyWindow()"
680  << " with three arguments if real energies are wanted for the"
681  << " PropertyExtractor."
682  );
683 
684  return lowerBound;
685 }
686 
687 inline double PropertyExtractor::getUpperBound() const{
688  TBTKAssert(
689  energyType == EnergyType::Real,
690  "PropertyExtractor::PropertyExtractor::getUpperBound()",
691  "The upper bound cannot be accessed when the energy type is"
692  << " Matsubara.",
693  "Use PropertyExtractor::PropertyExtractor::setEnergyWindow()"
694  << " with three arguments if real energies are wanted for the"
695  << " PropertyExtractor."
696  );
697 
698  return upperBound;
699 }
700 
702  TBTKAssert(
703  energyType == EnergyType::Matsubara,
704  "PropertyExtractor::PropertyExtractor::getLowerFermionicMatsubaraEnergyIndex()",
705  "The lower Fermionic Matsubara energy index cannot be accessed"
706  << " when the energy type is real.",
707  "Use PropertyExtractor::PropertyExtractor::setEnergyWindow()"
708  << " with four arguments if Matsubara energies are wanted for"
709  << " the PropertyExtractor."
710  );
711 
712  return lowerFermionicMatsubaraEnergyIndex;
713 }
714 
716  TBTKAssert(
717  energyType == EnergyType::Matsubara,
718  "PropertyExtractor::PropertyExtractor::getUpperFermionicMatsubaraEnergyIndex()",
719  "The upper Fermionic Matsubara energy index cannot be accessed"
720  << " when the energy type is real.",
721  "Use PropertyExtractor::PropertyExtractor::setEnergyWindow()"
722  << " with four arguments if Matsubara energies are wanted for"
723  << " the PropertyExtractor."
724  );
725 
726  return upperFermionicMatsubaraEnergyIndex;
727 }
728 
730  TBTKAssert(
731  energyType == EnergyType::Matsubara,
732  "PropertyExtractor::PropertyExtractor::getLowerBosonicMatsubaraEnergyIndex()",
733  "The lower Bosonic Matsubara energy index cannot be accessed"
734  << " when the energy type is real.",
735  "Use PropertyExtractor::PropertyExtractor::setEnergyWindow()"
736  << " with four arguments if Matsubara energies are wanted for"
737  << " the PropertyExtractor."
738  );
739 
740  return lowerBosonicMatsubaraEnergyIndex;
741 }
742 
744  TBTKAssert(
745  energyType == EnergyType::Matsubara,
746  "PropertyExtractor::PropertyExtractor::getUpperBosonicMatsubaraEnergyIndex()",
747  "The upper Bosonic Matsubara energy index cannot be accessed"
748  << " when the energy type is real.",
749  "Use PropertyExtractor::PropertyExtractor::setEnergyWindow()"
750  << " with four arguments if Matsubara energies are wanted for"
751  << " the PropertyExtractor."
752  );
753 
754  return upperBosonicMatsubaraEnergyIndex;
755 }
756 
757 inline double PropertyExtractor::getEnergyInfinitesimal() const{
758  return energyInfinitesimal;
759 }
760 
761 template<typename DataType>
763  void (*callback)(
764  PropertyExtractor *cb_this,
765  Property::Property &property,
766  const Index &index,
767  int offset,
768  Information &information
769  ),
771  Index pattern,
772  const Index &ranges,
773  int currentOffset,
774  int offsetMultiplier,
775  Information &information
776 ){
777  //Find the next specifier index.
778  int currentSubindex = pattern.getSize()-1;
779  for(; currentSubindex >= 0; currentSubindex--){
780  if(pattern.at(currentSubindex) < 0)
781  break;
782  }
783 
784  if(currentSubindex == -1){
785  //No further specifier index found. Call the callback.
786  callback(this, property, pattern, currentOffset, information);
787  }
788  else{
789  //Ensure that the specifier is valid for the Ranges format.
790  TBTKAssert(
791  pattern.at(currentSubindex).isSummationIndex()
792  || pattern.at(currentSubindex).isRangeIndex(),
793  "PropertyExtractor::calculate()",
794  "Invalid specifier found at subindex "
795  << currentSubindex << ".",
796  "Did you mean IDX_SUM_ALL, IDX_X, IDX_Y, or IDX_Z?"
797  );
798 
799  //Multiply the memory offset for non summation indices.
800  int nextOffsetMultiplier = offsetMultiplier;
801  if(!pattern.at(currentSubindex).isSummationIndex())
802  nextOffsetMultiplier *= ranges.at(currentSubindex);
803 
804  //Set flag indicating whether the current subindex is a
805  //summation index.
806  bool isSumIndex = false;
807  if(pattern.at(currentSubindex).isSummationIndex())
808  isSumIndex = true;
809 
810  //Recurively call the calculate function with the specifier at
811  //the current subindex replaced by each subindex value in the
812  //corresponding range.
813  for(int n = 0; n < ranges.at(currentSubindex); n++){
814  pattern.at(currentSubindex) = n;
815  calculate(
816  callback,
817  property,
818  pattern,
819  ranges,
820  currentOffset,
821  nextOffsetMultiplier,
822  information
823  );
824  if(!isSumIndex)
825  currentOffset += offsetMultiplier;
826  }
827  }
828 }
829 
830 template<typename DataType>
832  void (*callback)(
833  PropertyExtractor *cb_this,
834  Property::Property &property,
835  const Index &index,
836  int offset,
837  Information &information
838  ),
839  const IndexTree &allIndices,
840  const IndexTree &memoryLayout,
841  Property::AbstractProperty<DataType> &abstractProperty,
842  Information &information
843 ){
844  for(
845  IndexTree::ConstIterator iterator = allIndices.cbegin();
846  iterator != allIndices.end();
847  ++iterator
848  ){
849  const Index &index = *iterator;
850  std::vector<unsigned int> spinIndices
851  = memoryLayout.getSubindicesMatching(
852  IDX_SPIN,
853  index,
854  IndexTree::SearchMode::MatchWildcards
855  );
856  if(spinIndices.size() != 0){
857  TBTKAssert(
858  spinIndices.size() == 1,
859  "PropertyExtractor::calculate()",
860  "Several spin indeces found.",
861  "Use IDX_SPIN at most once per pattern to"
862  << " indicate spin index."
863  );
864  information.setSpinIndex(spinIndices[0]);
865  }
866 
867  callback(
868  this,
869  abstractProperty,
870  index,
871  abstractProperty.getOffset(index),
872  information
873  );
874  }
875 }
876 
878  this->spinIndex = spinIndex;
879 }
880 
882  return spinIndex;
883 }
884 
885 inline const Solver::Solver& PropertyExtractor::getSolver() const{
886  TBTKExit(
887  "PropertyExtractor::getSolver()",
888  "Missing implementation of PropertyExtractor::getSolver() in"
889  " deriving class.",
890  ""
891  );
892 }
893 
894 }; //End of namespace PropertyExtractor
895 }; //End of namespace TBTK
896 
897 #endif
Base class for Solvers.
Definition: Solver.h:42
virtual Property::SpinPolarizedLDOS calculateSpinPolarizedLDOS(Index pattern, Index ranges)
Property container for the local density of states (LDOS).
Definition: LDOS.h:48
bool isRangeIndex() const
Definition: Subindex.h:441
int getEnergyResolution() const
Definition: PropertyExtractor.h:659
double getUpperBound() const
Definition: PropertyExtractor.h:687
Physical index.
HoppingAmplitude container.
Definition: HoppingAmplitudeSet.h:50
int getSpinIndex() const
Definition: PropertyExtractor.h:881
EnergyType getEnergyType() const
Definition: PropertyExtractor.h:655
virtual std::complex< double > calculateExpectationValue(Index to, Index from)
Property container for magnetization.
Definition: Magnetization.h:44
Property container for local density of states (LDOS).
virtual void setEnergyInfinitesimal(double energyInfinitesimal)
ConstIterator cbegin() const
Definition: IndexTree.h:406
Subindex & at(unsigned int n)
Definition: Index.h:474
int getOffset(const Index &index) const
Definition: AbstractProperty.h:587
virtual void setEnergyWindow(double lowerBound, double upperBound, int energyResolution)
int getUpperBosonicMatsubaraEnergyIndex() const
Definition: PropertyExtractor.h:743
HoppingAmplitude container.
virtual Property::Density calculateDensity(Index pattern, Index ranges)
virtual Property::DOS sampleDOS(unsigned int numSamples, const std::vector< Index > &patterns={}, unsigned int seed=time(nullptr))
IndexTree generateIndexTree(std::vector< Index > patterns, const HoppingAmplitudeSet &hoppingAmplitudeSet, bool keepSummationWildcards, bool keepSpinWildcards)
Property container for spin-polarized local density of states (spin-polarized LDOS).
bool isSummationIndex() const
Definition: Subindex.h:437
void ensureCompliantRanges(const Index &pattern, Index &ranges)
Property container for density.
void setSpinIndex(int spinIndex)
Definition: PropertyExtractor.h:877
ConstIterator end() const
Definition: IndexTree.h:410
virtual Property::LDOS calculateLDOS(Index pattern, Index ranges)
Property container for magnetization.
Base class for Solvers.
Real number.
Definition: Real.h:33
Abstract Property class.
Definition: Property.h:36
unsigned int getSize() const
Definition: Index.h:482
Abstract Property class.
Definition: AbstractProperty.h:101
Data structure for mapping physical indices to linear indices.
Definition: IndexTree.h:35
Physical index.
Definition: Index.h:44
Definition: IndexTree.h:297
Base class for PropertyExtractors.
Definition: PropertyExtractor.h:64
Definition: Boolean.h:32
Property container for spin-polarized local density of states (spin-polarized LDOS).
Definition: SpinPolarizedLDOS.h:46
virtual Property::Magnetization calculateMagnetization(Index pattern, Index ranges)
Property container for density.
Definition: Density.h:43
Property container for density of states (DOS).
void calculate(void(*callback)(PropertyExtractor *cb_this, Property::Property &property, const Index &index, int offset, Information &information), Property::AbstractProperty< DataType > &property, Index pattern, const Index &ranges, int currentOffset, int offsetMultiplier, Information &information)
Definition: PropertyExtractor.h:762
int getLowerFermionicMatsubaraEnergyIndex() const
Definition: PropertyExtractor.h:701
double getLowerBound() const
Definition: PropertyExtractor.h:673
Property container for density of states (DOS).
Definition: DOS.h:48
int getLowerBosonicMatsubaraEnergyIndex() const
Definition: PropertyExtractor.h:729
EnergyType
Definition: PropertyExtractor.h:378
std::vector< unsigned int > getSubindicesMatching(int subindexValue, const Index &index, SearchMode searchMode) const
int getUpperFermionicMatsubaraEnergyIndex() const
Definition: PropertyExtractor.h:715
std::vector< int > getLoopRanges(const Index &pattern, const Index &ranges)