61 if(fProductionCutsTable ==
nullptr)
63 fProductionCutsTable = &theProductionCutsTable;
65 return fProductionCutsTable;
73 rangeCutTable.push_back(
new std::vector<G4double>);
74 energyCutTable.push_back(
new std::vector<G4double>);
75 rangeDoubleVector[i] =
nullptr;
76 energyDoubleVector[i] =
nullptr;
77 converters[i] =
nullptr;
89 delete defaultProductionCuts;
90 defaultProductionCuts =
nullptr;
92 for(
auto itr=coupleTable.cbegin(); itr!=coupleTable.cend(); ++itr)
100 delete rangeCutTable[i];
101 delete energyCutTable[i];
102 delete converters[i];
103 if(rangeDoubleVector[i] !=
nullptr)
delete [] rangeDoubleVector[i];
104 if(energyDoubleVector[i] !=
nullptr)
delete [] energyDoubleVector[i];
105 rangeCutTable[i] =
nullptr;
106 energyCutTable[i] =
nullptr;
107 converters[i] =
nullptr;
108 rangeDoubleVector[i] =
nullptr;
109 energyDoubleVector[i] =
nullptr;
112 delete userEnergyCuts[i];
115 fProductionCutsTable =
nullptr;
118 fMessenger =
nullptr;
127 ed <<
"Wrong index= " << idx <<
"; it should be < 4";
128 G4Exception(
"G4ProductionCutsTable::SetEnergyCutVector()",
132 userEnergyCuts[idx] =
new std::vector<G4double>(cutE);
139 for(
auto CoupleItr=coupleTable.cbegin();
140 CoupleItr!=coupleTable.cend(); ++CoupleItr)
142 (*CoupleItr)->SetUseFlag(
false);
146 for(
auto rItr=fG4RegionStore->cbegin(); rItr!=fG4RegionStore->cend(); ++rItr)
152 if( (*rItr)->IsInMassGeometry() || (*rItr)->IsInParallelGeometry() )
155 auto mItr = (*rItr)->GetMaterialIterator();
156 std::size_t nMaterial = (*rItr)->GetNumberOfMaterials();
159 for(std::size_t iMate=0; iMate<nMaterial; ++iMate)
162 G4bool coupleAlreadyDefined =
false;
164 for(
auto cItr=coupleTable.cbegin(); cItr!=coupleTable.cend(); ++cItr)
166 if( (*cItr)->GetMaterial()==(*mItr)
167 && (*cItr)->GetProductionCuts()==fProductionCut)
169 coupleAlreadyDefined =
true;
176 if(!coupleAlreadyDefined)
179 coupleTable.push_back(aCouple);
184 (*rItr)->RegisterMaterialCouplePair((*mItr),aCouple);
189 auto rootLVItr = (*rItr)->GetRootLogicalVolumeIterator();
190 std::size_t nRootLV = (*rItr)->GetNumberOfRootVolumes();
191 for(std::size_t iLV=0; iLV<nRootLV; ++iLV)
197 ScanAndSetCouple(aLV,aCouple,aR);
213 std::size_t nCouple = coupleTable.size();
214 std::size_t nTable = energyCutTable[0]->size();
215 G4bool newCoupleAppears = nCouple>nTable;
218 for(std::size_t n=nCouple-nTable; n>0; --n)
222 rangeCutTable[nn]->push_back(-1.);
223 energyCutTable[nn]->push_back(-1.);
233 G4double* rangeVOld = rangeDoubleVector[ix];
234 G4double* energyVOld = energyDoubleVector[ix];
235 if(rangeVOld)
delete [] rangeVOld;
236 if(energyVOld)
delete [] energyVOld;
237 rangeDoubleVector[ix] =
new G4double[(*(rangeCutTable[ix])).size()];
238 energyDoubleVector[ix] =
new G4double[(*(energyCutTable[ix])).size()];
280 for(
auto cItr=coupleTable.cbegin(); cItr!=coupleTable.cend(); ++cItr)
284 if((*cItr)->IsRecalcNeeded())
289 (*(rangeCutTable[ptcl]))[idx] = rCut;
291 if(
nullptr != converters[ptcl])
294 if(
nullptr == userEnergyCuts[ptcl] || userEnergyCuts[ptcl]->size() <= idx)
296 (*(energyCutTable[ptcl]))[idx] = converters[ptcl]->Convert(rCut,aMat);
300 (*(energyCutTable[ptcl]))[idx] = (*(userEnergyCuts[ptcl]))[idx];
305 (*(energyCutTable[ptcl]))[idx] = -1.;
314 G4cout <<
"G4ProductionCutsTable::UpdateCoupleTable() - "
315 <<
"Elapsed time for calculation of energy cuts: " <<
G4endl;
322 for(std::size_t ixx=0; ixx<(*(rangeCutTable[ix])).size(); ++ixx)
324 rangeDoubleVector[ix][ixx] = (*(rangeCutTable[ix]))[ixx];
325 energyDoubleVector[ix][ixx] = (*(energyCutTable[ix]))[ixx];
345 ed <<
"Invoked prematurely before it is fully initialized.";
346 G4Exception(
"G4ProductionCutsTable::ConvertRangeToEnergy()",
354 if (material ==
nullptr)
return -1.0;
357 if (range == 0.0)
return 0.0;
358 if (range <0.0)
return -1.0;
363 if (index<0 || converters[index] ==
nullptr)
370 if(particle !=
nullptr)
373 { ed <<
"without valid particle pointer."; }
374 G4Exception(
"G4ProductionCutsTable::ConvertRangeToEnergy()",
381 return converters[index]->
Convert(range, material);
412 if((aRegion!=
nullptr) && aLV->
GetRegion()!=aRegion)
return;
421 if(noDaughters==0)
return;
424 for(std::size_t i=0; i<noDaughters; ++i)
427 ScanAndSetCouple(daughterLVol,aCouple,aRegion);
435 G4cout <<
"========= Table of registered couples ============================"
437 for(
auto cItr=coupleTable.cbegin(); cItr!=coupleTable.cend(); ++cItr)
443 <<
" used in the geometry : ";
451 G4cout <<
" Range cuts : "
457 G4cout <<
" Energy thresholds : " ;
470 G4cout <<
" Region(s) which use this couple : " <<
G4endl;
471 for(
auto rItr=fG4RegionStore->cbegin();
472 rItr!=fG4RegionStore->cend(); ++rItr)
474 if (IsCoupleUsedInTheRegion(aCouple, *rItr) )
482 G4cout <<
"==================================================================" <<
G4endl;
499 G4cout <<
"G4ProductionCutsTable::StoreCutsTable()" <<
G4endl;
500 G4cout <<
" Material/Cuts information have been successfully stored ";
503 G4cout <<
" in Ascii mode ";
507 G4cout <<
" in Binary mode ";
524 G4cout <<
"G4ProductionCutsTable::RetrieveCutsTable()" <<
G4endl;
525 G4cout <<
" Material/Cuts information have been successfully retrieved ";
528 G4cout <<
" in Ascii mode ";
532 G4cout <<
" in Binary mode ";
548 G4cerr <<
"G4ProductionCutsTable::CheckForRetrieveCutsTable()"<<
G4endl;
553 G4cerr <<
"G4ProductionCutsTable::CheckMaterialInfo passed !!"<<
G4endl;
558 G4cerr <<
"G4ProductionCutsTable::CheckMaterialCutsCoupleInfo passed !!"
570 const G4String fileName = directory +
"/" +
"material.dat";
571 const G4String key =
"MATERIAL-V3.0";
575 if (!ascii ) fOut.open(fileName,std::ios::out|std::ios::binary);
576 else fOut.open(fileName,std::ios::out);
584 G4cerr <<
"G4ProductionCutsTable::StoreMaterialInfo() - ";
588 G4Exception(
"G4ProductionCutsTable::StoreMaterialInfo()",
595 G4int numberOfMaterial = (
G4int)matTable->size();
604 fOut << numberOfMaterial <<
G4endl;
606 fOut.setf(std::ios::scientific);
609 for (std::size_t idx=0;
static_cast<G4int>(idx)<numberOfMaterial; ++idx)
611 fOut << std::setw(FixedStringLengthForStore)
612 << ((*matTable)[idx])->GetName();
613 fOut << std::setw(FixedStringLengthForStore)
614 << ((*matTable)[idx])->GetDensity()/(g/cm3) <<
G4endl;
617 fOut.unsetf(std::ios::scientific);
623 char temp[FixedStringLengthForStore];
627 for (i=0; i<FixedStringLengthForStore; ++i)
631 for (i=0; i<key.length() && i<FixedStringLengthForStore-1; ++i)
633 temp[i]=key[(
G4int)i];
635 fOut.write(temp, FixedStringLengthForStore);
638 fOut.write( (
char*)(&numberOfMaterial),
sizeof(
G4int));
641 for (std::size_t imat=0;
static_cast<G4int>(imat)<numberOfMaterial; ++imat)
643 G4String name = ((*matTable)[imat])->GetName();
644 G4double density = ((*matTable)[imat])->GetDensity();
645 for (i=0; i<FixedStringLengthForStore; ++i)
647 for (i=0; i<name.length() && i<FixedStringLengthForStore-1; ++i)
648 temp[i]=name[(
G4int)i];
649 fOut.write(temp, FixedStringLengthForStore);
650 fOut.write( (
char*)(&density),
sizeof(
G4double));
664 const G4String fileName = directory +
"/" +
"material.dat";
665 const G4String key =
"MATERIAL-V3.0";
669 if (!ascii ) fIn.open(fileName,std::ios::in|std::ios::binary);
670 else fIn.open(fileName,std::ios::in);
678 G4cerr <<
"G4ProductionCutsTable::CheckMaterialInfo() - ";
682 G4Exception(
"G4ProductionCutsTable::CheckMaterialInfo()",
687 char temp[FixedStringLengthForStore];
697 fIn.read(temp, FixedStringLengthForStore);
698 keyword = (
const char*)(temp);
705 G4cerr <<
"G4ProductionCutsTable::CheckMaterialInfo() - ";
706 G4cerr <<
"Key word in " << fileName <<
"= " << keyword ;
710 G4Exception(
"G4ProductionCutsTable::CheckMaterialInfo()",
723 fIn.read( (
char*)(&nmat),
sizeof(
G4int));
725 if ((nmat<=0) || (nmat >100000))
727 G4Exception(
"G4ProductionCutsTable::CheckMaterialInfo()",
729 "Number of materials is less than zero or too big");
734 for (
G4int idx=0; idx<nmat ; ++idx)
742 G4cout <<
"G4ProductionCutsTable::CheckMaterialInfo() - ";
743 G4cout <<
"Encountered End of File " ;
752 char name[FixedStringLengthForStore];
756 fIn >> name >> density;
762 fIn.read(name, FixedStringLengthForStore);
763 fIn.read((
char*)(&density),
sizeof(
G4double));
770 G4cerr <<
"G4ProductionCutsTable::CheckMaterialInfo() - ";
771 G4cerr <<
"Bad data format ";
775 G4Exception(
"G4ProductionCutsTable::CheckMaterialInfo()",
782 if (aMaterial ==
nullptr )
continue;
785 if ((0.999>ratio) || (ratio>1.001) )
790 G4cerr <<
"G4ProductionCutsTable::CheckMaterialInfo() - ";
794 G4cerr <<
"Density:" << std::setiosflags(std::ios::scientific)
795 << density / (g/cm3) ;
798 G4cerr << std::resetiosflags(std::ios::scientific);
801 G4Exception(
"G4ProductionCutsTable::CheckMaterialInfo()",
802 "ProcCuts104",
JustWarning,
"Inconsistent material density");
819 const G4String fileName = directory +
"/" +
"couple.dat";
822 char temp[FixedStringLengthForStore];
825 if (!ascii ) fOut.open(fileName,std::ios::out|std::ios::binary);
826 else fOut.open(fileName,std::ios::out);
835 G4cerr <<
"G4ProductionCutsTable::StoreMaterialCutsCoupleInfo() - ";
839 G4Exception(
"G4ProductionCutsTable::StoreMaterialCutsCoupleInfo()",
844 G4int numberOfCouples = (
G4int)coupleTable.size();
849 fOut << std::setw(FixedStringLengthForStore) << key <<
G4endl;
852 fOut << numberOfCouples <<
G4endl;
859 for (i=0; i<FixedStringLengthForStore; ++i)
861 for (i=0; i<key.length() && i<FixedStringLengthForStore-1; ++i)
862 temp[i]=key[(
G4int)i];
863 fOut.write(temp, FixedStringLengthForStore);
866 fOut.write( (
char*)(&numberOfCouples),
sizeof(
G4int));
870 for (
auto cItr=coupleTable.cbegin(); cItr!=coupleTable.cend(); ++cItr)
886 for(
auto rItr=fG4RegionStore->cbegin();
887 rItr!=fG4RegionStore->cend(); ++rItr)
889 if (IsCoupleUsedInTheRegion(aCouple, *rItr))
891 regionName = (*rItr)->GetName();
904 fOut << std::setw(FixedStringLengthForStore) << materialName<<
G4endl;
907 fOut << std::setw(FixedStringLengthForStore) << regionName<<
G4endl;
909 fOut.setf(std::ios::scientific);
913 fOut << std::setw(FixedStringLengthForStore) << cutValues[idx]/(mm)
916 fOut.unsetf(std::ios::scientific);
923 fOut.write( (
char*)(&index),
sizeof(
G4int));
927 for (i=0; i<FixedStringLengthForStore; ++i)
929 for (i=0; i<materialName.length() && i<FixedStringLengthForStore-1; ++i)
930 temp[i]=materialName[(
G4int)i];
931 fOut.write(temp, FixedStringLengthForStore);
934 for (i=0; i<FixedStringLengthForStore; ++i)
936 for (i=0; i<regionName.length() && i<FixedStringLengthForStore-1; ++i)
937 temp[i]=regionName[(
G4int)i];
938 fOut.write(temp, FixedStringLengthForStore);
943 fOut.write( (
char*)(&(cutValues[idx])),
sizeof(
G4double));
959 const G4String fileName = directory +
"/" +
"couple.dat";
964 if (!ascii ) fIn.open(fileName,std::ios::in|std::ios::binary);
965 else fIn.open(fileName,std::ios::in);
973 G4cerr <<
"G4ProductionCutTable::CheckMaterialCutsCoupleInfo() - ";
977 G4Exception(
"G4ProductionCutsTable::CheckMaterialCutsCoupleInfo()",
982 char temp[FixedStringLengthForStore];
992 fIn.read(temp, FixedStringLengthForStore);
993 keyword = (
const char*)(temp);
1000 G4cerr <<
"G4ProductionCutTable::CheckMaterialCutsCoupleInfo() - ";
1001 G4cerr <<
"Key word in " << fileName <<
"= " << keyword ;
1005 G4Exception(
"G4ProductionCutsTable::CheckMaterialCutsCoupleInfo()",
1012 G4int numberOfCouples;
1015 fIn >> numberOfCouples;
1019 fIn.read( (
char*)(&numberOfCouples),
sizeof(
G4int));
1023 mccConversionTable.
Reset(numberOfCouples);
1026 for (
G4int idx=0; idx<numberOfCouples; ++idx)
1036 fIn.read( (
char*)(&index),
sizeof(
G4int));
1039 char mat_name[FixedStringLengthForStore];
1046 fIn.read(mat_name, FixedStringLengthForStore);
1049 char region_name[FixedStringLengthForStore];
1056 fIn.read(region_name, FixedStringLengthForStore);
1064 fIn >> cutValues[i];
1065 cutValues[i] *= (mm);
1069 fIn.read( (
char*)(&(cutValues[i])),
sizeof(
G4double));
1076 for (
auto cItr=coupleTable.cbegin(); cItr!=coupleTable.cend(); ++cItr)
1090 fRatio = fRatio && (0.999<ratio) && (ratio<1.001) ;
1093 if (!fRatio)
continue;
1104 if (verboseLevel >1)
1108 if ( regionname !=
"NONE" )
1110 fRegion = fG4RegionStore->
GetRegion(region_name);
1111 if (fRegion ==
nullptr)
1113 G4cout <<
"G4ProductionCutTable::CheckMaterialCutsCoupleInfo() - ";
1114 G4cout <<
"Region " << regionname <<
" is not found ";
1118 if (((regionname ==
"NONE") && (aCouple->
IsUsed()))
1119 || ((fRegion!=
nullptr) && !IsCoupleUsedInTheRegion(aCouple, fRegion)))
1121 G4cout <<
"G4ProductionCutTable::CheckMaterialCutsCoupleInfo()"
1123 G4cout <<
"A Couple is used different region in the current setup ";
1125 G4cout <<
" material: " << mat_name ;
1129 G4cout <<
"cut[" << ii <<
"]=" << cutValues[ii]/mm;
1134 else if ( index != aCouple->
GetIndex() )
1136 G4cout <<
"G4ProductionCutTable::CheckMaterialCutsCoupleInfo() - ";
1140 G4cout <<
" is defined as " ;
1141 G4cout << index <<
":" << mat_name <<
" in " << fileName <<
G4endl;
1145 G4cout <<
"G4ProductionCutTable::CheckMaterialCutsCoupleInfo() - ";
1146 G4cout << index <<
":" << mat_name <<
" in " << fileName ;
1147 G4cout <<
" is consistent with current setup" <<
G4endl;
1155 if (verboseLevel >0)
1157 G4cout <<
"G4ProductionCutTable::CheckMaterialCutsCoupleInfo()"
1159 G4cout <<
"Couples are not defined in the current detector setup ";
1161 G4cout <<
" material: " << mat_name ;
1165 G4cout <<
"cut[" << ii <<
"]=" << cutValues[ii]/mm;
1183 const G4String fileName = directory +
"/" +
"cut.dat";
1186 char temp[FixedStringLengthForStore];
1189 if (!ascii ) fOut.open(fileName,std::ios::out|std::ios::binary);
1190 else fOut.open(fileName,std::ios::out);
1197 G4cerr <<
"G4ProductionCutsTable::StoreCutsInfo() - ";
1200 G4Exception(
"G4ProductionCutsTable::StoreCutsInfo()",
1205 G4int numberOfCouples = (
G4int)coupleTable.size();
1213 fOut << numberOfCouples <<
G4endl;
1220 for (i=0; i<FixedStringLengthForStore; ++i)
1222 for (i=0; i<key.length() && i<FixedStringLengthForStore-1; ++i)
1223 temp[i]=key[(
G4int)i];
1224 fOut.write(temp, FixedStringLengthForStore);
1227 fOut.write( (
char*)(&numberOfCouples),
sizeof(
G4int));
1236 for (
auto cItr=coupleTable.cbegin();cItr!=coupleTable.cend(); ++cItr, ++i)
1241 fOut.setf(std::ios::scientific);
1242 fOut << std::setw(20) << (*fRange)[i]/mm ;
1243 fOut << std::setw(20) << (*fEnergy)[i]/keV <<
G4endl;
1244 fOut.unsetf(std::ios::scientific);
1250 fOut.write((
char*)(&cut),
sizeof(
G4double));
1251 cut = (*fEnergy)[i];
1252 fOut.write((
char*)(&cut),
sizeof(
G4double));
1266 const G4String fileName = directory +
"/" +
"cut.dat";
1271 if (!ascii ) fIn.open(fileName,std::ios::in|std::ios::binary);
1272 else fIn.open(fileName,std::ios::in);
1277 if (verboseLevel >0)
1279 G4cerr <<
"G4ProductionCutTable::RetrieveCutsInfo() - ";
1282 G4Exception(
"G4ProductionCutsTable::RetrieveCutsInfo()",
1287 char temp[FixedStringLengthForStore];
1297 fIn.read(temp, FixedStringLengthForStore);
1298 keyword = (
const char*)(temp);
1302 if (verboseLevel >0)
1304 G4cerr <<
"G4ProductionCutTable::RetrieveCutsInfo() - ";
1305 G4cerr <<
"Key word in " << fileName <<
"= " << keyword ;
1308 G4Exception(
"G4ProductionCutsTable::RetrieveCutsInfo()",
1314 G4int numberOfCouples;
1317 fIn >> numberOfCouples;
1320 G4Exception(
"G4ProductionCutsTable::RetrieveCutsInfo()",
1327 fIn.read( (
char*)(&numberOfCouples),
sizeof(
G4int));
1330 if (numberOfCouples >
static_cast<G4int>(mccConversionTable.
size()) )
1332 G4Exception(
"G4ProductionCutsTable::RetrieveCutsInfo()",
1334 "Number of Couples in the file exceeds defined couples");
1336 numberOfCouples = (
G4int)mccConversionTable.
size();
1340 std::vector<G4double>* fRange = rangeCutTable[idx];
1341 std::vector<G4double>* fEnergy = energyCutTable[idx];
1346 for (std::size_t i=0;
static_cast<G4int>(i)< numberOfCouples; ++i)
1351 fIn >> rcut >> ecut;
1354 G4Exception(
"G4ProductionCutsTable::RetrieveCutsInfo()",
1363 fIn.read((
char*)(&rcut),
sizeof(
G4double));
1364 fIn.read((
char*)(&ecut),
sizeof(
G4double));
1366 if (!mccConversionTable.
IsUsed(i))
continue;
1367 std::size_t new_index = mccConversionTable.
GetIndex(i);
1368 (*fRange)[new_index] = rcut;
1369 (*fEnergy)[new_index] = ecut;
1380 verboseLevel = value;
1383 if (converters[ip] !=
nullptr )
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
std::vector< G4Material * > G4MaterialTable
G4GLOB_DLL std::ostream G4cerr
G4GLOB_DLL std::ostream G4cout
std::size_t GetNoDaughters() const
G4Region * GetRegion() const
G4Material * GetMaterial() const
G4VPhysicalVolume * GetDaughter(const std::size_t i) const
void SetMaterialCutsCouple(G4MaterialCutsCouple *cuts)
void SetNewIndex(std::size_t index, std::size_t new_value)
G4bool IsUsed(std::size_t index) const
G4int GetIndex(std::size_t index) const
void Reset(std::size_t size)
const G4Material * GetMaterial() const
void SetUseFlag(G4bool flg=true)
G4ProductionCuts * GetProductionCuts() const
G4double GetDensity() const
static G4MaterialTable * GetMaterialTable()
const G4String & GetName() const
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
const G4String & GetParticleName() const
static G4ParticleTable * GetParticleTable()
const std::vector< G4double > * GetRangeCutsVector(std::size_t pcIdx) const
virtual G4bool RetrieveCutsInfo(const G4String &directory, G4bool ascii=false)
G4bool RetrieveCutsTable(const G4String &directory, G4bool ascii=false)
virtual G4bool StoreCutsInfo(const G4String &directory, G4bool ascii=false)
G4double GetLowEdgeEnergy() const
void SetMaxEnergyCut(G4double value)
void UpdateCoupleTable(G4VPhysicalVolume *currentWorld)
G4double GetMaxEnergyCut()
void SetVerboseLevel(G4int value)
virtual G4bool CheckMaterialInfo(const G4String &directory, G4bool ascii=false)
G4int GetVerboseLevel() const
virtual G4bool StoreMaterialInfo(const G4String &directory, G4bool ascii=false)
G4double GetHighEdgeEnergy() const
virtual ~G4ProductionCutsTable()
const std::vector< G4double > * GetEnergyCutsVector(std::size_t pcIdx) const
G4bool StoreCutsTable(const G4String &directory, G4bool ascii=false)
G4bool CheckForRetrieveCutsTable(const G4String &directory, G4bool ascii=false)
void CreateCoupleTables()
void SetEnergyRange(G4double lowedge, G4double highedge)
static G4ProductionCutsTable * GetProductionCutsTable()
virtual G4bool CheckMaterialCutsCoupleInfo(const G4String &directory, G4bool ascii=false)
void SetEnergyCutVector(const std::vector< G4double > &cutE, std::size_t idx)
G4double ConvertRangeToEnergy(const G4ParticleDefinition *particle, const G4Material *material, G4double range)
virtual G4bool StoreMaterialCutsCoupleInfo(const G4String &directory, G4bool ascii=false)
static G4int GetIndex(const G4String &name)
G4double GetProductionCut(G4int index) const
const std::vector< G4double > & GetProductionCuts() const
static G4RegionStore * GetInstance()
G4Region * GetRegion(const G4String &name, G4bool verbose=true) const
G4LogicalVolume * GetLogicalVolume() const
static void SetMaxEnergyCut(const G4double value)
void SetVerboseLevel(G4int value)
static G4double GetMaxEnergyCut()
virtual G4double Convert(const G4double rangeCut, const G4Material *material)
static void SetEnergyRange(const G4double lowedge, const G4double highedge)
static G4double GetLowEdgeEnergy()
static G4double GetHighEdgeEnergy()