TBTK
Need a break? Support the development by playing Polarity Puzzles
EnergyResolvedProperty.h
Go to the documentation of this file.
1 /* Copyright 2018 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_ENERGY_RESOLVED_PROPERTY
24 #define COM_DAFER45_TBTK_PROPERTY_ENERGY_RESOLVED_PROPERTY
25 
26 #include "TBTK/Property/AbstractProperty.h"
27 #include "TBTK/TBTKMacros.h"
28 
29 #include <cmath>
30 #include <complex>
31 #include <vector>
32 
33 namespace TBTK{
34 namespace Property{
35 
82 template<typename DataType>
83 class EnergyResolvedProperty : public AbstractProperty<DataType>{
84 public:
86  enum class EnergyType{Real, FermionicMatsubara, BosonicMatsubara};
87 
90 
99  double lowerBound,
100  double upperBound,
101  unsigned int resolution
102  );
103 
114  double lowerBound,
115  double upperBound,
116  unsigned int resolution,
117  const DataType *data
118  );
119 
132  const std::vector<int> &ranges,
133  double lowerBound,
134  double upperBound,
135  unsigned int resolution
136  );
137 
152  const std::vector<int> &ranges,
153  double lowerBound,
154  double upperBound,
155  unsigned int resolution,
156  const DataType *data
157  );
158 
170  const IndexTree &indexTree,
171  double lowerBound,
172  double upperBound,
173  unsigned int resolution
174  );
175 
190  const IndexTree &indexTree,
191  double lowerBound,
192  double upperBound,
193  unsigned int resolution,
194  const DataType *data
195  );
196 
208  EnergyType energyType,
209  const IndexTree &indexTree,
210  int lowerMatsubaraEnergyIndex,
211  int upperMatsubaraEnergtIndex,
212  double fundamentalMatsubaraEnergy
213  );
214 
229  EnergyType energyType,
230  const IndexTree &indexTree,
231  int lowerMatsubaraEnergyIndex,
232  int upperMatsubaraEnergtIndex,
233  double fundamentalMatsubaraEnergy,
234  const DataType *data
235  );
236 
243  const std::string &serialization,
244  Serializable::Mode mode
245  );
246 
247  /*** Get energy type.
248  *
249  * @return The EnergyType. */
250  EnergyType getEnergyType() const;
251 
255  double getLowerBound() const;
256 
260  double getUpperBound() const;
261 
266  unsigned int getResolution() const;
267 
272  double getDeltaE() const;
273 
279  double getEnergy(unsigned int n) const;
280 
285  int getLowerMatsubaraEnergyIndex() const;
286 
292  int getUpperMatsubaraEnergyIndex() const;
293 
297  unsigned int getNumMatsubaraEnergies() const;
298 
301  double getFundamentalMatsubaraEnergy() const;
302 
306  double getLowerMatsubaraEnergy() const;
307 
311  double getUpperMatsubaraEnergy() const;
312 
314  std::complex<double> getMatsubaraEnergy(unsigned int n) const;
315 
322  unsigned int getNumEnergies() const;
323 
339  const EnergyResolvedProperty &energyResolvedProperty,
340  double precision = 1e-1
341  ) const;
342 
344  virtual std::string serialize(Serializable::Mode mode) const;
345 protected:
348 
351 
353  EnergyResolvedProperty& operator*=(const DataType &rhs);
354 
356  EnergyResolvedProperty& operator/=(const DataType &rhs);
357 private:
359  EnergyType energyType;
360 
361  class RealEnergy{
362  public:
364  double lowerBound;
365 
367  double upperBound;
368 
370  unsigned int resolution;
371  };
372 
373  class MatsubaraEnergy{
374  public:
376  int lowerMatsubaraEnergyIndex;
377 
379  int numMatsubaraEnergies;
380 
382  double fundamentalMatsubaraEnergy;
383  };
384 
386  union EnergyDescriptor{
387  RealEnergy realEnergy;
388  MatsubaraEnergy matsubaraEnergy;
389  };
390 
392  EnergyDescriptor descriptor;
393 };
394 
395 template<typename DataType>
397 }
398 
399 template<typename DataType>
401  double lowerBound,
402  double upperBound,
403  unsigned int resolution
404 ) :
405  AbstractProperty<DataType>(resolution)
406 {
407  TBTKAssert(
408  lowerBound <= upperBound,
409  "EnergyResolvedProperty::EnergyResolvedProperty()",
410  "Invalid energy bounds. The 'lowerBound=" << lowerBound << "'"
411  " must be less or equal to the 'upperBound=" << upperBound
412  << "'.",
413  ""
414  );
415  TBTKAssert(
416  resolution > 0,
417  "EnergyResolvedProperty::EnergyResolvedProperty()",
418  "The 'resolution' must be larger than 0.",
419  ""
420  );
421 
422  energyType = EnergyType::Real;
423  descriptor.realEnergy.lowerBound = lowerBound;
424  descriptor.realEnergy.upperBound = upperBound;
425  descriptor.realEnergy.resolution = resolution;
426 }
427 
428 template<typename DataType>
430  double lowerBound,
431  double upperBound,
432  unsigned int resolution,
433  const DataType *data
434 ) :
435  AbstractProperty<DataType>(resolution, data)
436 {
437  TBTKAssert(
438  lowerBound <= upperBound,
439  "EnergyResolvedProperty::EnergyResolvedProperty()",
440  "Invalid energy bounds. The 'lowerBound=" << lowerBound << "'"
441  " must be less or equal to the 'upperBound=" << upperBound
442  << "'.",
443  ""
444  );
445  TBTKAssert(
446  resolution > 0,
447  "EnergyResolvedProperty::EnergyResolvedProperty()",
448  "The 'resolution' must be larger than 0.",
449  ""
450  );
451 
452  energyType = EnergyType::Real;
453  descriptor.realEnergy.lowerBound = lowerBound;
454  descriptor.realEnergy.upperBound = upperBound;
455  descriptor.realEnergy.resolution = resolution;
456 }
457 
458 template<typename DataType>
460  const std::vector<int> &ranges,
461  double lowerBound,
462  double upperBound,
463  unsigned int resolution
464 ) :
465  AbstractProperty<DataType>(ranges, resolution)
466 {
467  TBTKAssert(
468  lowerBound <= upperBound,
469  "EnergyResolvedProperty::EnergyResolvedProperty()",
470  "Invalid energy bounds. The 'lowerBound=" << lowerBound << "'"
471  " must be less or equal to the 'upperBound=" << upperBound
472  << "'.",
473  ""
474  );
475  TBTKAssert(
476  resolution > 0,
477  "EnergyResolvedProperty::EnergyResolvedProperty()",
478  "The 'resolution' must be larger than 0.",
479  ""
480  );
481 
482  energyType = EnergyType::Real;
483  descriptor.realEnergy.lowerBound = lowerBound;
484  descriptor.realEnergy.upperBound = upperBound;
485  descriptor.realEnergy.resolution = resolution;
486 }
487 
488 template<typename DataType>
490  const std::vector<int> &ranges,
491  double lowerBound,
492  double upperBound,
493  unsigned int resolution,
494  const DataType *data
495 ) :
496  AbstractProperty<DataType>(ranges, resolution, data)
497 {
498  TBTKAssert(
499  lowerBound <= upperBound,
500  "EnergyResolvedProperty::EnergyResolvedProperty()",
501  "Invalid energy bounds. The 'lowerBound=" << lowerBound << "'"
502  " must be less or equal to the 'upperBound=" << upperBound
503  << "'.",
504  ""
505  );
506  TBTKAssert(
507  resolution > 0,
508  "EnergyResolvedProperty::EnergyResolvedProperty()",
509  "The 'resolution' must be larger than 0.",
510  ""
511  );
512 
513  energyType = EnergyType::Real;
514  descriptor.realEnergy.lowerBound = lowerBound;
515  descriptor.realEnergy.upperBound = upperBound;
516  descriptor.realEnergy.resolution = resolution;
517 }
518 
519 template<typename DataType>
521  const IndexTree &indexTree,
522  double lowerBound,
523  double upperBound,
524  unsigned int resolution
525 ) :
526  AbstractProperty<DataType>(indexTree, resolution)
527 {
528  TBTKAssert(
529  lowerBound <= upperBound,
530  "EnergyResolvedProperty::EnergyResolvedProperty()",
531  "Invalid energy bounds. The 'lowerBound=" << lowerBound << "'"
532  " must be less or equal to the 'upperBound=" << upperBound
533  << "'.",
534  ""
535  );
536  TBTKAssert(
537  resolution > 0,
538  "EnergyResolvedProperty::EnergyResolvedProperty()",
539  "The 'resolution' must be larger than 0.",
540  ""
541  );
542 
543  energyType = EnergyType::Real;
544  descriptor.realEnergy.lowerBound = lowerBound;
545  descriptor.realEnergy.upperBound = upperBound;
546  descriptor.realEnergy.resolution = resolution;
547 }
548 
549 template<typename DataType>
551  const IndexTree &indexTree,
552  double lowerBound,
553  double upperBound,
554  unsigned int resolution,
555  const DataType *data
556 ) :
557  AbstractProperty<DataType>(indexTree, resolution, data)
558 {
559  TBTKAssert(
560  lowerBound < upperBound,
561  "EnergyResolvedProperty::EnergyResolvedProperty()",
562  "Invalid energy bounds. The 'lowerBound=" << lowerBound << "'"
563  " must be smaller than the 'upperBound=" << upperBound << "'.",
564  ""
565  );
566  TBTKAssert(
567  resolution > 0,
568  "EnergyResolvedProperty::EnergyResolvedProperty()",
569  "The 'resolution' must be larger than 0.",
570  ""
571  );
572 
573  energyType = EnergyType::Real;
574  descriptor.realEnergy.lowerBound = lowerBound;
575  descriptor.realEnergy.upperBound = upperBound;
576  descriptor.realEnergy.resolution = resolution;
577 }
578 
579 template<typename DataType>
581  EnergyType energyType,
582  const IndexTree &indexTree,
583  int lowerMatsubaraEnergyIndex,
584  int upperMatsubaraEnergyIndex,
585  double fundamentalMatsubaraEnergy
586 ) :
587  AbstractProperty<DataType>(
588  indexTree,
589  (upperMatsubaraEnergyIndex-lowerMatsubaraEnergyIndex)/2 + 1
590  )
591 {
592  TBTKAssert(
593  lowerMatsubaraEnergyIndex <= upperMatsubaraEnergyIndex,
594  "EnergyResolvedProperty::EnergyResolvedProperty()",
595  "Invalid Matsubara energy bounds. The"
596  " 'lowerMatsubaraEnergyIndex=" << lowerMatsubaraEnergyIndex
597  << "' must be less or equal to the 'upperMatsubaraEnergyIndex="
598  << upperMatsubaraEnergyIndex << "'.",
599  ""
600  );
601  TBTKAssert(
602  fundamentalMatsubaraEnergy > 0,
603  "EnergyResolvedProperty::energyResolvedProperty()",
604  "The 'fundamentalMatsubaraEnergy' must be larger than 0.",
605  ""
606  );
607 
608  switch(energyType){
609  case EnergyType::FermionicMatsubara:
610  TBTKAssert(
611  abs(lowerMatsubaraEnergyIndex%2) == 1,
612  "EnergyResolvedProperty::EnergyResolvedProperty()",
613  "The 'lowerMatsubaraEnergyIndex="
614  << lowerMatsubaraEnergyIndex << "' must be odd for"
615  << " EnergyType::FermionicMatsubara.",
616  ""
617  );
618  TBTKAssert(
619  abs(upperMatsubaraEnergyIndex%2) == 1,
620  "EnergyResolvedProperty::EnergyResolvedProperty()",
621  "The 'upperMatsubaraEnergyIndex="
622  << upperMatsubaraEnergyIndex << "' must be odd for"
623  << " EnergyType::FermionicMatsubara.",
624  ""
625  );
626 
627  this->energyType = energyType;
628  descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
629  = lowerMatsubaraEnergyIndex;
630  descriptor.matsubaraEnergy.numMatsubaraEnergies = (
631  upperMatsubaraEnergyIndex-lowerMatsubaraEnergyIndex)/2
632  + 1;
633  descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
634  = fundamentalMatsubaraEnergy;
635 
636  break;
637  case EnergyType::BosonicMatsubara:
638  TBTKAssert(
639  lowerMatsubaraEnergyIndex%2 == 0,
640  "EnergyResolvedProperty::EnergyResolvedProperty()",
641  "The 'lowerMatsubaraEnergyIndex="
642  << lowerMatsubaraEnergyIndex << "' must be even for"
643  << " EnergyType::BosonicMatsubara.",
644  ""
645  );
646  TBTKAssert(
647  upperMatsubaraEnergyIndex%2 == 0,
648  "EnergyResolvedProperty::EnergyResolvedProperty()",
649  "The 'upperMatsubaraEnergyIndex="
650  << upperMatsubaraEnergyIndex << "' must be even for"
651  << " EnergyType::BosonicMatsubara.",
652  ""
653  );
654 
655  this->energyType = energyType;
656  descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
657  = lowerMatsubaraEnergyIndex;
658  descriptor.matsubaraEnergy.numMatsubaraEnergies = (
659  upperMatsubaraEnergyIndex-lowerMatsubaraEnergyIndex)/2
660  + 1;
661  descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
662  = fundamentalMatsubaraEnergy;
663 
664  break;
665  default:
666  TBTKExit(
667  "EnergyResolvedProperty::EnergyResolvedProperty()",
668  "The 'energyType' must be"
669  " EnergyType::FermionicMatsubara or"
670  " EnergyType::BosonicMatsubara.",
671  ""
672  );
673  }
674 }
675 
676 template<typename DataType>
678  EnergyType energyType,
679  const IndexTree &indexTree,
680  int lowerMatsubaraEnergyIndex,
681  int upperMatsubaraEnergyIndex,
682  double fundamentalMatsubaraEnergy,
683  const DataType *data
684 ) :
685  AbstractProperty<DataType>(
686  indexTree,
687  (upperMatsubaraEnergyIndex-lowerMatsubaraEnergyIndex)/2 + 1,
688  data
689  )
690 {
691  TBTKAssert(
692  lowerMatsubaraEnergyIndex <= upperMatsubaraEnergyIndex,
693  "EnergyResolvedProperty::EnergyResolvedProperty()",
694  "Invalid Matsubara energy bounds. The"
695  " 'lowerMatsubaraEnergyIndex=" << lowerMatsubaraEnergyIndex
696  << "' must be less or equal to the 'upperMatsubaraEnergyIndex="
697  << upperMatsubaraEnergyIndex << "'.",
698  ""
699  );
700  TBTKAssert(
701  fundamentalMatsubaraEnergy > 0,
702  "EnergyResolvedProperty::energyResolvedProperty()",
703  "The 'fundamentalMatsubaraEnergy' must be larger than 0.",
704  ""
705  );
706 
707  switch(energyType){
708  case EnergyType::FermionicMatsubara:
709  TBTKAssert(
710  abs(lowerMatsubaraEnergyIndex%2) == 1,
711  "EnergyResolvedProperty::EnergyResolvedProperty()",
712  "The 'lowerMatsubaraEnergyIndex="
713  << lowerMatsubaraEnergyIndex << "' must be odd for"
714  << " EnergyType::FermionicMatsubara.",
715  ""
716  );
717  TBTKAssert(
718  abs(upperMatsubaraEnergyIndex%2) == 1,
719  "EnergyResolvedProperty::EnergyResolvedProperty()",
720  "The 'uppererMatsubaraEnergyIndex="
721  << upperMatsubaraEnergyIndex << "' must be odd for"
722  << " EnergyType::FermionicMatsubara.",
723  ""
724  );
725 
726  this->energyType = energyType;
727  descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
728  = lowerMatsubaraEnergyIndex;
729  descriptor.matsubaraEnergy.numMatsubaraEnergies = (
730  upperMatsubaraEnergyIndex-lowerMatsubaraEnergyIndex)/2
731  + 1;
732  descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
733  = fundamentalMatsubaraEnergy;
734 
735  break;
736  case EnergyType::BosonicMatsubara:
737  TBTKAssert(
738  lowerMatsubaraEnergyIndex%2 == 0,
739  "EnergyResolvedProperty::EnergyResolvedProperty()",
740  "The 'lowerMatsubaraEnergyIndex="
741  << lowerMatsubaraEnergyIndex << "' must be even for"
742  << " EnergyType::BosonicMatsubara.",
743  ""
744  );
745  TBTKAssert(
746  upperMatsubaraEnergyIndex%2 == 0,
747  "EnergyResolvedProperty::EnergyResolvedProperty()",
748  "The 'uppererMatsubaraEnergyIndex="
749  << upperMatsubaraEnergyIndex << "' must be even for"
750  << " EnergyType::BosonicMatsubara.",
751  ""
752  );
753 
754  this->energyType = energyType;
755  descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
756  = lowerMatsubaraEnergyIndex;
757  descriptor.matsubaraEnergy.numMatsubaraEnergies = (
758  upperMatsubaraEnergyIndex-lowerMatsubaraEnergyIndex)/2
759  + 1;
760  descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
761  = fundamentalMatsubaraEnergy;
762 
763  break;
764  default:
765  TBTKExit(
766  "EnergyResolvedProperty::EnergyResolvedProperty()",
767  "The 'energyType' must be"
768  " EnergyType::FermionicMatsubara or"
769  " EnergyType::BosonicMatsubara.",
770  ""
771  );
772  }
773 }
774 
775 template<typename DataType>
777  const std::string &serialization,
778  Serializable::Mode mode
779 ) :
780  AbstractProperty<DataType>(
781  Serializable::extract(
782  serialization,
783  mode,
784  "abstractProperty"
785  ),
786  mode
787  )
788 {
789  TBTKAssert(
790  Serializable::validate(serialization, "EnergyResolvedProperty", mode),
791  "Property::EnergyResolvedProperty::EnergyResolvedProperty()",
792  "Unable to parse string as EnergyResolvedProperty '"
793  << serialization << "'.",
794  ""
795  );
796 
797  switch(mode){
798  case Serializable::Mode::JSON:
799  try{
800  nlohmann::json j = nlohmann::json::parse(serialization);
801  std::string et = j.at("energyType").get<std::string>();
802  if(et.compare("Real") == 0){
803  energyType = EnergyType::Real;
804  descriptor.realEnergy.lowerBound
805  = j.at("lowerBound").get<double>();
806  descriptor.realEnergy.upperBound
807  = j.at("upperBound").get<double>();
808  descriptor.realEnergy.resolution
809  = j.at("resolution").get<double>();
810  }
811  else if(et.compare("FermionicMatsubara") == 0){
812  energyType = EnergyType::FermionicMatsubara;
813  descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
814  = j.at("lowerMatsubaraEnergyIndex");
815  descriptor.matsubaraEnergy.numMatsubaraEnergies
816  = j.at("numMatsubaraEnergies");
817  descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
818  = j.at("fundamentalMatsubaraEnergy");
819  }
820  else if(et.compare("BosonicMatsubara") == 0){
821  energyType = EnergyType::BosonicMatsubara;
822  descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
823  = j.at("lowerMatsubaraEnergyIndex");
824  descriptor.matsubaraEnergy.numMatsubaraEnergies
825  = j.at("numMatsubaraEnergies");
826  descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
827  = j.at("fundamentalMatsubaraEnergy");
828  }
829  }
830  catch(nlohmann::json::exception &e){
831  TBTKExit(
832  "Proerty::EnergyResolvedProperty::EnergyResolvedProperty()",
833  "Unable to parse string as"
834  << " EnergyResolvedProperty '" << serialization
835  << "'.",
836  ""
837  );
838  }
839 
840  break;
841  default:
842  TBTKExit(
843  "Property::EnergyResolvedProperty::EnergyResolvedProperty()",
844  "Only Serializable::Mode::JSON is supported yet.",
845  ""
846  );
847  }
848 }
849 
850 template<typename DataType>
853  return energyType;
854 }
855 
856 template<typename DataType>
858  TBTKAssert(
859  energyType == EnergyType::Real,
860  "EnergyResolvedProperty::getLowerBound()",
861  "The Property is not of the type EnergyType::Real.",
862  ""
863  );
864 
865  return descriptor.realEnergy.lowerBound;
866 }
867 
868 template<typename DataType>
870  TBTKAssert(
871  energyType == EnergyType::Real,
872  "EnergyResolvedProperty::getUpperBound()",
873  "The Property is not of the type EnergyType::Real.",
874  ""
875  );
876 
877  return descriptor.realEnergy.upperBound;
878 }
879 
880 template<typename DataType>
882  TBTKAssert(
883  energyType == EnergyType::Real,
884  "EnergyResolvedProperty::getResolution()",
885  "The Property is not of the type EnergyType::Real.",
886  ""
887  );
888 
889  return descriptor.realEnergy.resolution;
890 }
891 
892 template<typename DataType>
894  TBTKAssert(
895  energyType == EnergyType::Real,
896  "EnergyResolvedProperty::getDeltaE()",
897  "The Property is not of the type EnergyType::Real.",
898  ""
899  );
900 
901  double dE;
902  if(descriptor.realEnergy.resolution == 1)
903  dE = 0;
904  else
905  dE = (
906  descriptor.realEnergy.upperBound
907  - descriptor.realEnergy.lowerBound
908  )/(descriptor.realEnergy.resolution - 1);
909 
910  return dE;
911 }
912 
913 template<typename DataType>
915  unsigned int n
916 ) const{
917  TBTKAssert(
918  energyType == EnergyType::Real,
919  "EnergyResolvedProperty::getEnergy()",
920  "The Property is not of the type EnergyType::Real.",
921  ""
922  );
923 
924  return descriptor.realEnergy.lowerBound + ((int)n)*getDeltaE();
925 }
926 
927 template<typename DataType>
929 ) const{
930  TBTKAssert(
931  energyType == EnergyType::FermionicMatsubara
932  || energyType == EnergyType::BosonicMatsubara,
933  "EnergyResolvedProperty::getLowerMatsubaraEnergyIndex()",
934  "The Property is not of the type"
935  << " EnergyType::FermionicMatsubara or"
936  << " EnergyType::BosonicMatsubara.",
937  ""
938  );
939 
940  return descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex;
941 }
942 
943 template<typename DataType>
945 ) const{
946  TBTKAssert(
947  energyType == EnergyType::FermionicMatsubara
948  || energyType == EnergyType::BosonicMatsubara,
949  "EnergyResolvedProperty::getUpperMatsubaraEnergyIndex()",
950  "The Property is not of the type"
951  << " EnergyType::FermionicMatsubara or"
952  << " EnergyType::BosonicMatsubara.",
953  ""
954  );
955 
956  return descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
957  + 2*(descriptor.matsubaraEnergy.numMatsubaraEnergies - 1);
958 }
959 
960 template<typename DataType>
962  TBTKAssert(
963  energyType == EnergyType::FermionicMatsubara
964  || energyType == EnergyType::BosonicMatsubara,
965  "EnergyResolvedProperty::getNumMatsubaraEnergies()",
966  "The Property is not of the type"
967  << " EnergyType::FermionicMatsubara or"
968  << " EnergyType::BosonicMatsubara.",
969  ""
970  );
971 
972  return descriptor.matsubaraEnergy.numMatsubaraEnergies;
973 }
974 
975 template<typename DataType>
976 inline double EnergyResolvedProperty<
977  DataType
978 >::getFundamentalMatsubaraEnergy() const{
979  TBTKAssert(
980  energyType == EnergyType::FermionicMatsubara
981  || energyType == EnergyType::BosonicMatsubara,
982  "EnergyResolvedProperty::getFundamentalMatsubaraEnergy()",
983  "The Property is not of the type"
984  << " EnergyType::FermionicMatsubara or"
985  << " EnergyType::BosonicMatsubara.",
986  ""
987  );
988 
989  return descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy;
990 }
991 
992 template<typename DataType>
994 ) const{
995  TBTKAssert(
996  energyType == EnergyType::FermionicMatsubara
997  || energyType == EnergyType::BosonicMatsubara,
998  "EnergyResolvedProperty::getLowerMatsubaraEnergy()",
999  "The Property is not of the type"
1000  << " EnergyType::FermionicMatsubara or"
1001  << " EnergyType::BosonicMatsubara.",
1002  ""
1003  );
1004 
1005  return descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
1006  *descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy;
1007 }
1008 
1009 template<typename DataType>
1011 ) const{
1012  TBTKAssert(
1013  energyType == EnergyType::FermionicMatsubara
1014  || energyType == EnergyType::BosonicMatsubara,
1015  "EnergyResolvedProperty::getUpperMatsubaraEnergyIndex()",
1016  "The Property is not of the type"
1017  << " EnergyType::FermionicMatsubara or"
1018  << " EnergyType::BosonicMatsubara.",
1019  ""
1020  );
1021 
1022  return (
1023  descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
1024  + 2*(descriptor.matsubaraEnergy.numMatsubaraEnergies-1)
1025  )*descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy;
1026 }
1027 
1028 template<typename DataType>
1029 inline std::complex<double> EnergyResolvedProperty<
1030  DataType
1031 >::getMatsubaraEnergy(
1032  unsigned int n
1033 ) const{
1034  TBTKAssert(
1035  energyType == EnergyType::FermionicMatsubara
1036  || energyType == EnergyType::BosonicMatsubara,
1037  "EnergyResolvedProperty::getMatsubaraEnergy()",
1038  "The Property is not of the type"
1039  << " EnergyType::FermionicMatsubara or"
1040  << " EnergyType::BosonicMatsubara.",
1041  ""
1042  );
1043 
1044  return std::complex<double>(
1045  0,
1046  (descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex + 2*(int)n)
1047  *descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
1048  );
1049 }
1050 
1051 template<typename DataType>
1053  switch(energyType){
1054  case EnergyType::Real:
1055  return getResolution();
1056  case EnergyType::FermionicMatsubara:
1057  case EnergyType::BosonicMatsubara:
1058  return getNumMatsubaraEnergies();
1059  default:
1060  TBTKExit(
1061  "Property::EnergyResolvedProperty::getNumEnergies()",
1062  "Unknown energy type.",
1063  "This should never happen, contact the developer."
1064  );
1065  }
1066 }
1067 
1068 template<typename DataType>
1070  const EnergyResolvedProperty &energyResolvedProperty,
1071  double precision
1072 ) const{
1073  if(energyType != energyResolvedProperty.energyType)
1074  return false;
1075 
1076  if(getNumEnergies() != energyResolvedProperty.getNumEnergies())
1077  return false;
1078 
1079  switch(energyType){
1080  case EnergyType::Real:
1081  {
1082  double lowerBound0 = getLowerBound();
1083  double upperBound0 = getUpperBound();
1084  double lowerBound1 = energyResolvedProperty.getLowerBound();
1085  double upperBound1 = energyResolvedProperty.getUpperBound();
1086  double dE = getDeltaE();
1087 
1088  if(std::abs(lowerBound0 - lowerBound1) > precision*dE)
1089  return false;
1090  if(std::abs(upperBound0 - upperBound1) > precision*dE)
1091  return false;
1092 
1093  return true;
1094  }
1095  case EnergyType::FermionicMatsubara:
1096  case EnergyType::BosonicMatsubara:
1097  {
1098  double lowerMatsubaraEnergy0 = getLowerMatsubaraEnergy();
1099  double upperMatsubaraEnergy0 = getUpperMatsubaraEnergy();
1100  double lowerMatsubaraEnergy1
1101  = energyResolvedProperty.getLowerMatsubaraEnergy();
1102  double upperMatsubaraEnergy1
1103  = energyResolvedProperty.getUpperMatsubaraEnergy();
1104  double dE;
1105  if(getNumEnergies() > 1)
1106  dE = imag(getMatsubaraEnergy(1) - getMatsubaraEnergy(0));
1107  else
1108  dE = 0;
1109 
1110  if(
1111  std::abs(lowerMatsubaraEnergy0 - lowerMatsubaraEnergy1)
1112  > precision*dE
1113  ){
1114  return false;
1115  }
1116  if(
1117  std::abs(upperMatsubaraEnergy0 - upperMatsubaraEnergy1)
1118  > precision*dE
1119  ){
1120  return false;
1121  }
1122 
1123  return true;
1124  }
1125  default:
1126  TBTKExit(
1127  "Property::EnergyResolvedProperty::energyWindowsAreEqual()",
1128  "Unknown energy type.",
1129  "This should never happen, contact the developer."
1130  );
1131  }
1132 }
1133 
1134 template<typename DataType>
1136  Serializable::Mode mode
1137 ) const{
1138  switch(mode){
1139  case Serializable::Mode::JSON:
1140  {
1141  nlohmann::json j;
1142  j["id"] = "EnergyResolvedProperty";
1143  switch(energyType){
1144  case EnergyType::Real:
1145  j["energyType"] = "Real";
1146  j["lowerBound"] = descriptor.realEnergy.lowerBound;
1147  j["upperBound"] = descriptor.realEnergy.upperBound;
1148  j["resolution"] = descriptor.realEnergy.resolution;
1149 
1150  break;
1151  case EnergyType::FermionicMatsubara:
1152  j["energyType"] = "FermionicMatsubara";
1153  j["lowerMatsubaraEnergyIndex"]
1154  = descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex;
1155  j["numMatsubaraEnergies"]
1156  = descriptor.matsubaraEnergy.numMatsubaraEnergies;
1157  j["fundamentalMatsubaraEnergy"]
1158  = descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy;
1159 
1160  break;
1161  case EnergyType::BosonicMatsubara:
1162  j["energyType"] = "BosonicMatsubara";
1163  j["lowerMatsubaraEnergyIndex"]
1164  = descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex;
1165  j["numMatsubaraEnergies"]
1166  = descriptor.matsubaraEnergy.numMatsubaraEnergies;
1167  j["fundamentalMatsubaraEnergy"]
1168  = descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy;
1169 
1170  break;
1171  default:
1172  TBTKExit(
1173  "Property::EnergyResolvedProperty::serialize()",
1174  "Unknown EnergyType.",
1175  "This should never happen, contact the developer."
1176  );
1177  }
1178  j["abstractProperty"] = nlohmann::json::parse(
1180  );
1181 
1182  return j.dump();
1183  }
1184  default:
1185  TBTKExit(
1186  "Property::EnergyResolvedProperty::serialize()",
1187  "Only Serializable::Mode::JSON is supported yet.",
1188  ""
1189  );
1190  }
1191 }
1192 
1193 template<typename DataType>
1197 ){
1198  TBTKAssert(
1199  energyType == rhs.energyType,
1200  "Property::EnergyResolvedProperty::operator+=()",
1201  "Incompatible energy types.",
1202  ""
1203  );
1204 
1205  switch(energyType){
1206  case EnergyType::Real:
1207  TBTKAssert(
1208  descriptor.realEnergy.lowerBound
1209  == rhs.descriptor.realEnergy.lowerBound,
1210  "Property::EnergyResolvedProperty::operator+=()",
1211  "Incompatible energy bounds. The left hand side has"
1212  << " lower bound '" << descriptor.realEnergy.lowerBound
1213  << "', while the right hand side has lower bound '"
1214  << rhs.descriptor.realEnergy.lowerBound << "'.",
1215  ""
1216  );
1217  TBTKAssert(
1218  descriptor.realEnergy.upperBound
1219  == rhs.descriptor.realEnergy.upperBound,
1220  "Property::EnergyResolvedProperty::operator+=()",
1221  "Incompatible energy bounds. The left hand side has"
1222  << " upper bound '" << descriptor.realEnergy.upperBound
1223  << "', while the right hand side has upper bound '"
1224  << rhs.descriptor.realEnergy.upperBound << "'.",
1225  ""
1226  );
1227  TBTKAssert(
1228  descriptor.realEnergy.resolution
1229  == rhs.descriptor.realEnergy.resolution,
1230  "Property::EnergyResolvedProperty::operator+=()",
1231  "Incompatible energy resolution. The left hand side"
1232  << " has resolution '"
1233  << descriptor.realEnergy.resolution << "', while the"
1234  << " right hand side has resolution '"
1235  << rhs.descriptor.realEnergy.resolution << "'.",
1236  ""
1237  );
1238  case EnergyType::FermionicMatsubara:
1239  case EnergyType::BosonicMatsubara:
1240  TBTKAssert(
1241  descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
1242  == rhs.descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex,
1243  "Property::EnergyResolvedProperty::operator+=()",
1244  "Incompatible Matsubara energies. The left hand side"
1245  << " has lower Matsubara energy index '"
1246  << descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
1247  << "', while the right hand side has lower Matsubara"
1248  << " energy index '"
1249  << rhs.descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex << "'.",
1250  ""
1251  );
1252  TBTKAssert(
1253  descriptor.matsubaraEnergy.numMatsubaraEnergies
1254  == rhs.descriptor.matsubaraEnergy.numMatsubaraEnergies,
1255  "Property::EnergyResolvedProperty::operator+=()",
1256  "Incompatible Matsubara energies. The left hand side"
1257  << " has '"
1258  << descriptor.matsubaraEnergy.numMatsubaraEnergies
1259  << "' number of Matsubara energies, while the right"
1260  << " hand side has '"
1261  << rhs.descriptor.matsubaraEnergy.numMatsubaraEnergies
1262  << "' number of Matsubara energies.",
1263  ""
1264  );
1265  TBTKAssert(
1266  descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
1267  == rhs.descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy,
1268  "Property::EnergyResolvedProperty::operator+=()",
1269  "Incompatible Matsubara energies. The left hand side"
1270  << " has fundamental Matsubara energy '"
1271  << descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
1272  << "', while the right hand side has fundamental Matsubara"
1273  << " energy '"
1274  << rhs.descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
1275  << "'.",
1276  ""
1277  );
1278  }
1279 
1281 
1282  return *this;
1283 }
1284 
1285 template<typename DataType>
1289 ){
1290  TBTKAssert(
1291  energyType == rhs.energyType,
1292  "Property::EnergyResolvedProperty::operator-=()",
1293  "Incompatible energy types.",
1294  ""
1295  );
1296 
1297  switch(energyType){
1298  case EnergyType::Real:
1299  TBTKAssert(
1300  descriptor.realEnergy.lowerBound
1301  == rhs.descriptor.realEnergy.lowerBound,
1302  "Property::EnergyResolvedProperty::operator-=()",
1303  "Incompatible energy bounds. The left hand side has"
1304  << " lower bound '" << descriptor.realEnergy.lowerBound
1305  << "', while the right hand side has lower bound '"
1306  << rhs.descriptor.realEnergy.lowerBound << "'.",
1307  ""
1308  );
1309  TBTKAssert(
1310  descriptor.realEnergy.upperBound
1311  == rhs.descriptor.realEnergy.upperBound,
1312  "Property::EnergyResolvedProperty::operator-=()",
1313  "Incompatible energy bounds. The left hand side has"
1314  << " upper bound '" << descriptor.realEnergy.upperBound
1315  << "', while the right hand side has upper bound '"
1316  << rhs.descriptor.realEnergy.upperBound << "'.",
1317  ""
1318  );
1319  TBTKAssert(
1320  descriptor.realEnergy.resolution
1321  == rhs.descriptor.realEnergy.resolution,
1322  "Property::EnergyResolvedProperty::operator-=()",
1323  "Incompatible energy resolution. The left hand side"
1324  << " has resolution '"
1325  << descriptor.realEnergy.resolution << "', while the"
1326  << " right hand side has resolution '"
1327  << rhs.descriptor.realEnergy.resolution << "'.",
1328  ""
1329  );
1330  case EnergyType::FermionicMatsubara:
1331  case EnergyType::BosonicMatsubara:
1332  TBTKAssert(
1333  descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
1334  == rhs.descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex,
1335  "Property::EnergyResolvedProperty::operator-=()",
1336  "Incompatible Matsubara energies. The left hand side"
1337  << " has lower Matsubara energy index '"
1338  << descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex
1339  << "', while the right hand side has lower Matsubara"
1340  << " energy index '"
1341  << rhs.descriptor.matsubaraEnergy.lowerMatsubaraEnergyIndex << "'.",
1342  ""
1343  );
1344  TBTKAssert(
1345  descriptor.matsubaraEnergy.numMatsubaraEnergies
1346  == rhs.descriptor.matsubaraEnergy.numMatsubaraEnergies,
1347  "Property::EnergyResolvedProperty::operator-=()",
1348  "Incompatible Matsubara energies. The left hand side"
1349  << " has '"
1350  << descriptor.matsubaraEnergy.numMatsubaraEnergies
1351  << "' number of Matsubara energies, while the right"
1352  << " hand side has '"
1353  << rhs.descriptor.matsubaraEnergy.numMatsubaraEnergies
1354  << "' number of Matsubara energies.",
1355  ""
1356  );
1357  TBTKAssert(
1358  descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
1359  == rhs.descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy,
1360  "Property::EnergyResolvedProperty::operator-=()",
1361  "Incompatible Matsubara energies. The left hand side"
1362  << " has fundamental Matsubara energy '"
1363  << descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
1364  << "', while the right hand side has fundamental Matsubara"
1365  << " energy '"
1366  << rhs.descriptor.matsubaraEnergy.fundamentalMatsubaraEnergy
1367  << "'.",
1368  ""
1369  );
1370  }
1371 
1373 
1374  return *this;
1375 }
1376 
1377 template<typename DataType>
1380  const DataType &rhs
1381 ){
1383 
1384  return *this;
1385 }
1386 
1387 template<typename DataType>
1390  const DataType &rhs
1391 ){
1393 
1394  return *this;
1395 }
1396 
1397 }; //End namespace Property
1398 }; //End namespace TBTK
1399 
1400 #endif
unsigned int getNumEnergies() const
Definition: EnergyResolvedProperty.h:1052
unsigned int getResolution() const
Definition: EnergyResolvedProperty.h:881
virtual std::string serialize(Serializable::Mode mode) const
Definition: EnergyResolvedProperty.h:1135
Precompiler macros.
Definition: Serializable.h:43
double getLowerBound() const
Definition: EnergyResolvedProperty.h:857
double getEnergy(unsigned int n) const
Definition: EnergyResolvedProperty.h:914
Base class for energy resolved Properties.
Definition: EnergyResolvedProperty.h:83
bool energyWindowsAreEqual(const EnergyResolvedProperty &energyResolvedProperty, double precision=1e-1) const
Definition: EnergyResolvedProperty.h:1069
double getUpperBound() const
Definition: EnergyResolvedProperty.h:869
double getDeltaE() const
Definition: EnergyResolvedProperty.h:893
std::complex< double > getMatsubaraEnergy(unsigned int n) const
Definition: EnergyResolvedProperty.h:1031
double getLowerMatsubaraEnergy() const
Definition: EnergyResolvedProperty.h:993
Real number.
Definition: Real.h:33
EnergyResolvedProperty & operator*=(const DataType &rhs)
Definition: EnergyResolvedProperty.h:1379
Abstract Property class.
Definition: AbstractProperty.h:101
Data structure for mapping physical indices to linear indices.
Definition: IndexTree.h:35
EnergyResolvedProperty & operator-=(const EnergyResolvedProperty &rhs)
Definition: EnergyResolvedProperty.h:1287
EnergyResolvedProperty()
Definition: EnergyResolvedProperty.h:396
Definition: Boolean.h:32
double getFundamentalMatsubaraEnergy() const
Definition: EnergyResolvedProperty.h:978
unsigned int getNumMatsubaraEnergies() const
Definition: EnergyResolvedProperty.h:961
EnergyResolvedProperty & operator/=(const DataType &rhs)
Definition: EnergyResolvedProperty.h:1389
int getUpperMatsubaraEnergyIndex() const
Definition: EnergyResolvedProperty.h:944
int getLowerMatsubaraEnergyIndex() const
Definition: EnergyResolvedProperty.h:928
Mode
Definition: Serializable.h:47
double getUpperMatsubaraEnergy() const
Definition: EnergyResolvedProperty.h:1010
EnergyType
Definition: EnergyResolvedProperty.h:86
EnergyResolvedProperty & operator+=(const EnergyResolvedProperty &rhs)
Definition: EnergyResolvedProperty.h:1195