From 5b50993c2ce17aa61a3c0e473418cf4affbf65e8 Mon Sep 17 00:00:00 2001 From: Wiarda <wiardada@ornl.gov> Date: Thu, 16 Sep 2021 10:37:16 -0400 Subject: [PATCH] Make the calcCross function a procedure on CrossSectionCalculator. This way we can call it as a normal virtual function. Let CrossSectionCalcDriver only have one CrossSectionCalculator Unfortunately that needs to be a pointer to the R-Matrix formalism that is actually used. --- sammy/src/clq/ArtificalCross_M.f90 | 9 +- sammy/src/mlb/mmlb2.f90 | 46 ++-- sammy/src/mlb/mmlb3.f90 | 6 +- sammy/src/mlb/mmlb4.f90 | 4 +- sammy/src/the/CrossSectionCalcDriver_M.f90 | 249 +++++++-------------- sammy/src/the/CrossSectionCalculator_M.f90 | 20 ++ 6 files changed, 145 insertions(+), 189 deletions(-) diff --git a/sammy/src/clq/ArtificalCross_M.f90 b/sammy/src/clq/ArtificalCross_M.f90 index c9ed83730..4de7e5290 100644 --- a/sammy/src/clq/ArtificalCross_M.f90 +++ b/sammy/src/clq/ArtificalCross_M.f90 @@ -22,7 +22,7 @@ module ArtificalCross_M procedure, pass(this) :: initialize => ArtificalCross_initialize procedure, pass(this) :: destroy => ArtificalCross_destroy procedure, pass(this) :: setRange => ArtificalCross_setRange - procedure, pass(this) :: calculate => ArtificalCross_calculate + procedure, pass(this) :: calcCross => ArtificalCross_calcCross procedure, pass(this) :: print => ArtificalCross_print end type ArtificalCross @@ -156,9 +156,10 @@ subroutine ArtificalCross_print(this) END IF end subroutine -subroutine ArtificalCross_calculate(this, ener) - class(ArtificalCross) :: this - real(kind=8)::ener +subroutine ArtificalCross_calcCross(this, ener, Ipoten) + class(ArtificalCross) :: this + real(kind=8)::ener + integer::ipoten real(kind=8)::Su, Squ, Sigxxx, X diff --git a/sammy/src/mlb/mmlb2.f90 b/sammy/src/mlb/mmlb2.f90 index de615e707..44243fded 100755 --- a/sammy/src/mlb/mmlb2.f90 +++ b/sammy/src/mlb/mmlb2.f90 @@ -1,39 +1,51 @@ -module mmlb2_m +module MlbwCrossCalcImpl_m use MlbwCrossCalc_M + use CrossSectionCalculator_M use mmlb4_m implicit none + + type, extends(MlbwCrossCalc) :: MlbwCrossCalcImpl + contains + procedure, pass(this) :: calcCross => MlbwCrossCalcImpl_calcCross + end type + contains - subroutine MlbwCrossCalc_calculateCross(calculator, ener, Ipoten) - class(MlbwCrossCalc) :: calculator + subroutine MlbwCrossCalcImpl_calcCross(this, ener, Ipoten) + class(MlbwCrossCalcImpl) ::this real(kind=8)::ener integer::ipoten real(kind=8)::val integer::i, itot + logical(C_BOOL)::accu - itot = calculator%covariance%getNumTotalParam() - call calculator%crossData%reserveColumns(calculator%row, itot + 1) + call CrossSectionCalculator_calcCross(this, ener, Ipoten) if (ener.eq.0.0d0) return - calculator%ener = ener - IF (calculator%ener.LT.0.0d0) calculator%ener = -calculator%ener - calculator%enerSq = dSQRT(calculator%ener) + IF (this%ener.LT.0.0d0) this%ener = -this%ener - CALL Abpart_Mlb (calculator) - CALL Parsh_Mlb ( calculator, Ipoten) + CALL Abpart_Mlb (this) + CALL Parsh_Mlb (this, Ipoten) - if (ener.lt.0.0d0) then + if (ener.lt.0.0d0) then + itot = this%covariance%getNumTotalParam() + 1 + if ( .not.this%wantDerivs) itot = 1 + + accu = .false. + call this%crossData%setAccumulate(accu) do i = 0, itot - val = calculator%crossData%getData(calculator%row, i, 1) + val = this%crossData%getData(this%row, i, 1) if (val.ne.0.0d0) then - ! addData accumulates. So to change the sign, - ! subtract twice the original value - val = -2.0d0*val - call calculator%crossData%addData(calculator%row, i, 1, val) + val = -val + call this%crossData%addData(this%row, i, 1, val) end if end do + accu = .true. + call this%crossData%setAccumulate(accu) end if + + this%ener = ener end subroutine -end module mmlb2_m +end module MlbwCrossCalcImpl_m diff --git a/sammy/src/mlb/mmlb3.f90 b/sammy/src/mlb/mmlb3.f90 index 876c996c3..5f5e2c743 100644 --- a/sammy/src/mlb/mmlb3.f90 +++ b/sammy/src/mlb/mmlb3.f90 @@ -15,7 +15,7 @@ contains ! use constn_common_m, only : Pi100 ! - type(MlbwCrossCalc)::calculator + class(MlbwCrossCalc)::calculator real(kind=8),intent(in)::Goj integer, intent(in)::Nent, Next, If_Zke, Iso, igr, ipar @@ -127,7 +127,7 @@ contains ! real(kind=8),intent(in)::Goj integer,intent(in)::Nent, Next, If_Zke, igr, ipar - type(MlbwCrossCalc)::calculator + class(MlbwCrossCalc)::calculator real(kind=8)::val, Zero, Sum, Sum1, Sum2 real(kind=8)::A,B,C @@ -196,7 +196,7 @@ contains use constn_common_m, only : Pi100 use SammySpinGroupInfo_M ! - type(MlbwCrossCalc)::calculator + class(MlbwCrossCalc)::calculator type(SammySpinGroupInfo)::spinInfo integer::imin, ipar diff --git a/sammy/src/mlb/mmlb4.f90 b/sammy/src/mlb/mmlb4.f90 index 9606498f5..2285c3fbe 100644 --- a/sammy/src/mlb/mmlb4.f90 +++ b/sammy/src/mlb/mmlb4.f90 @@ -21,7 +21,7 @@ module mmlb4_m use RMatResonanceParam_M use xxx3 ! - type(MlbwCrossCalc)::calculator + class(MlbwCrossCalc)::calculator type(SammyResonanceInfo)::resInfo type(SammySpinGroupInfo)::spinInfo type(RMatResonance)::resonance @@ -233,7 +233,7 @@ module mmlb4_m use xxx6 ! ! - type(MlbwCrossCalc)::calculator + class(MlbwCrossCalc)::calculator integer::Ipoten type(SammySpinGroupInfo)::spinInfo diff --git a/sammy/src/the/CrossSectionCalcDriver_M.f90 b/sammy/src/the/CrossSectionCalcDriver_M.f90 index 73c55515e..2b08c3700 100644 --- a/sammy/src/the/CrossSectionCalcDriver_M.f90 +++ b/sammy/src/the/CrossSectionCalcDriver_M.f90 @@ -1,6 +1,6 @@ module CrossSectionCalcDriver_M use CrossSectionCalculator_M - use MlbwCrossCalc_M + use MlbwCrossCalcImpl_m use CroCrossCalc_M use XctCrossCalc_M use ArtificalCross_M @@ -12,23 +12,18 @@ module CrossSectionCalcDriver_M type CrossSectionCalcDriver - ! what kind of cross section do we want - type(MlbwCrossCalc)::mlbw ! multi-level (or single level) Breit-Wigner - logical::mlbwInit=.false. - - type(ArtificalCross)::artifical ! artificial cross section data for testing - logical::artificalInit=.false. - - type(CroCrossCalc)::cro ! old style Reich-Moore (no multi-isotope no angular) - logical::croInit=.false. - - type(XctCrossCalc)::xct ! new style Reich-Moore - logical::xctInit=.false. - ! arrays to take the cross section and derivative data type(DerivativeHandler)::calcData type(DerivativeHandler)::calcDataSelf ! used if self-indication experiments are calculated + class(CrossSectionCalculator),pointer::calculator + logical::calculatorInit + + type(ArtificalCross),pointer::artificalCalc => null() + type(MlbwCrossCalcImpl),pointer,private::mlbwCalc => null() + type(CroCrossCalc),pointer,private::croCalc => null() + type(XctCrossCalc),pointer,private::xctCalc => null() + logical::wantCrossPerSpin = .false. ! do we want cross section per spin group type(GridData)::crossPerSpin ! if used: energy, group 1, group 1 + group 2, group 1 + group 2 + group 3, ... repeated for each Nnnsig value ) @@ -51,7 +46,7 @@ module CrossSectionCalcDriver_M procedure, pass(this) :: setWantCrossPerSpin => CrossSectionCalcDriver_setWantCrossPerSpin ! indicate whether we want cross section per spin end type CrossSectionCalcDriver - private setup_desiredCross, setUpCommonData + private setup_desiredCross contains subroutine CrossSectionCalcDriver_initialize(this, calcData, calcDataSelf, kwcoul, Kssmsc, Kcros) @@ -87,61 +82,66 @@ module CrossSectionCalcDriver_M IF (this%Kcros.EQ.11) needAngular = .true. first = .false. - if (Kkkclq.NE.0) THEN - if (.not.this%artificalInit) then - call this%artifical%initialize(resParData, covData, radFitFlags, 1, needAngular, Itzero, Ilzero) - this%artifical%Kkclqx = Kkclqx - this%artifical%Kkkclq = Kkkclq - - this%artificalInit = .true. - first = .true. - end if - call setUpCommonData(this, this%artifical, first, this%Kcros, covData, resParData, radFitFlags, wantDeriv) - ELSE IF (Krmatx.EQ.1 .OR. Krmatx.EQ.-1) THEN - if (.not.this%mlbwInit) then - call this%mlbw%initialize(resParData, covData, radFitFlags, 1, needAngular, Itzero, Ilzero) - this%mlbw%wantMlbw = .false. - if (Krmatx.eq.1) then - this%mlbw%wantMlbw = .true. - else if (Krmatx.eq.-1) then - this%mlbw%wantMlbw = .false. - else - STOP '[STOP in mlb/mmlb0.f expect MLBW or SLBW]' - end if - - this%mlbwInit = .true. - first = .true. - end if - call setUpCommonData(this, this%mlbw, first, this%Kcros, covData, resParData, radFitFlags, wantDeriv) - ELSE IF (Krmatx.EQ.0) THEN - if (.not.this%croInit) then - call this%cro%initialize(resParData, covData, radFitFlags, 1, needAngular, Itzero, Ilzero) - - this%croInit = .true. - first = .true. - end if - call setUpCommonData(this, this%cro, first, this%Kcros, covData, resParData, radFitFlags, wantDeriv) - ELSE IF (Krmatx.EQ.2) THEN - if (.not.this%xctInit) then - nisoOur = niso - if (needAngular) then - call info%initialize(resParData, covData, radFitFlags) - iq = info%getNumUniqEchanIncludedChannels() - if( iq.gt.nisoOur) nisoOur = iq - call info%destroy() - end if - - call this%xct%initialize(resParData, covData, radFitFlags, nisoOur, needAngular, Itzero, Ilzero) - - this%xctInit = .true. - first = .true. + nisoOur = 1 + if (.not.this%calculatorInit) then + if (Kkkclq.NE.0) THEN + allocate(this%artificalCalc) + call this%artificalCalc%initialize(resParData, covData, radFitFlags, 1, needAngular, Itzero, Ilzero) + this%artificalCalc%Kkclqx = Kkclqx + this%artificalCalc%Kkkclq = Kkkclq + this%calculator => this%artificalCalc + ELSE IF (Krmatx.EQ.1 .OR. Krmatx.EQ.-1) THEN + allocate(this%mlbwCalc) + call this%mlbwCalc%initialize(resParData, covData, radFitFlags, 1, needAngular, Itzero, Ilzero) + if (Krmatx.eq.1) then + this%mlbwCalc%wantMlbw = .true. + else if (Krmatx.eq.-1) then + this%mlbwCalc%wantMlbw = .false. + else + STOP '[STOP in mlb/mmlb0.f expect MLBW or SLBW]' + end if + this%calculator => this%mlbwCalc + ELSE IF (Krmatx.EQ.0) THEN + allocate(this%croCalc) + call this%croCalc%initialize(resParData, covData, radFitFlags, 1, needAngular, Itzero, Ilzero) + this%calculator => this%croCalc + ELSE IF (Krmatx.EQ.2) THEN + nisoOur = niso + if (needAngular) then + call info%initialize(resParData, covData, radFitFlags) + iq = info%getNumUniqEchanIncludedChannels() + if( iq.gt.nisoOur) nisoOur = iq + call info%destroy() + end if + allocate(this%xctCalc) + call this%xctCalc%initialize(resParData, covData, radFitFlags, nisoOur, needAngular, Itzero, Ilzero) + this%calculator => this%xctCalc + ELSE + write(0,*)" Invalid selection for cross section calculator" + stop end if - call setUpCommonData(this, this%xct, first, this%Kcros, covData, resParData, radFitFlags, wantDeriv) + this%calculatorInit = .true. + first = .true. end if + + this%calculator%crossData%instance_ptr = this%calcData%instance_ptr + if (first) then + call this%calculator%crossData%setUpList(resParData, radFitFlags, nisoOur) + else + ! unfortunately they sometimes get redefined + this%calculator%resData%instance_ptr = resParData%instance_ptr + this%calculator%covariance%instance_ptr = covData%instance_ptr + this%calculator%radiusData%instance_ptr = radFitFlags%instance_ptr + end if + + this%calculator%reactType = this%Kcros + call setup_desiredCross(this, this%calculator) + call this%calculator%setWantDeriv(wantDeriv) + call this%calculator%setUpDerivativeList() + call this%calculator%setEnergyIndependent(this%Kcros, Twomhb, this%kwcoul, Etac) end subroutine subroutine CrossSectionCalcDriver_calcCross(this, row, ener, Ipoten) - use mmlb2_m class(CrossSectionCalcDriver)::this real(kind=8)::ener integer::ipoten, row @@ -153,21 +153,9 @@ module CrossSectionCalcDriver_M call this%calcData%setAccumulate(empty) - if (this%mlbwInit) then - this%mlbw%row = row - ! the specific call is here instead - ! a call function for the this%mlbw, because - ! MlbwCrossCalc_calculateCross relies - ! on data in this%mlbw - ! this avoids a circular dependence - call MlbwCrossCalc_calculateCross(this%mlbw, ener, Ipoten) - else if (this%artificalInit) then - this%artifical%row = row - call this%artifical%calculate(ener) - else if (this%croInit) then - this%cro%row = row - else if (this%xctInit) then - this%xct%row = row + if (this%calculatorInit) then + this%calculator%row = row + call this%calculator%calcCross( ener, Ipoten) else write(0,*)" Cross section calculator not initialized" stop @@ -179,33 +167,6 @@ module CrossSectionCalcDriver_M end subroutine - subroutine setUpCommonData(this, calc, first, Kcros, covData, resParData, radFitFlags, wantDeriv) - class(CrossSectionCalcDriver)::this - class(CrossSectionCalculator)::calc - logical::first, wantDeriv - integer::Kcros - type(SammyRMatrixParameters)::resParData - type(CovarianceData)::covData - type(AdjustedRadiusData)::radFitFlags - - calc%crossData%instance_ptr = this%calcData%instance_ptr - if (first) then - call calc%crossData%setUpList(resParData, radFitFlags, calc%numIso) - else - ! unfortunately they sometimes get redefined - calc%resData%instance_ptr = resParData%instance_ptr - calc%covariance%instance_ptr = covData%instance_ptr - calc%radiusData%instance_ptr = radFitFlags%instance_ptr - end if - - calc%reactType = Kcros - call setup_desiredCross(this, calc) - call calc%setWantDeriv(wantDeriv) - call calc%setUpDerivativeList() - call calc%setEnergyIndependent(Kcros, Twomhb, this%kwcoul, Etac) - end subroutine setUpCommonData - - subroutine setup_desiredCross(this, calc) use fixedi_m, only : Kaptur use ifwrit_m, only : Kaverg, Kfinit, Krecon @@ -292,33 +253,22 @@ module CrossSectionCalcDriver_M subroutine CrossSectionCalcDriver_destroy(this) class(CrossSectionCalcDriver)::this - if (this%mlbwInit) call this%mlbw%destroy() - this%mlbwInit = .false. - if (this%artificalInit) call this%artifical%destroy() - this%artificalInit = .false. - if (this%croInit) call this%cro%destroy() - this%croInit = .false. - if (this%xctInit) call this%xct%destroy() - this%xctInit = .false. - - if (this%wantCrossPerSpin) then - call this%crossPerSpin%destroy() - this%wantCrossPerSpin = .false. + if (this%calculatorInit) then + call this%calculator%destroy() end if + this%calculatorInit = .false. + if (associated(this%artificalCalc)) deallocate(this%artificalCalc) + if (associated(this%mlbwCalc)) deallocate(this%mlbwCalc) + if (associated(this%croCalc)) deallocate(this%croCalc) + if (associated(this%xctCalc)) deallocate(this%xctCalc) end subroutine subroutine CrossSectionCalcDriver_getAbundanceFromSpinGroup(this, setAbund) class(CrossSectionCalcDriver)::this logical::setAbund - if (this%mlbwInit) then - this%mlbw%getAbundanceFromSpinGroup = setAbund - else if (this%artificalInit) then - this%artifical%getAbundanceFromSpinGroup = setAbund - else if (this%croInit) then - this%cro%getAbundanceFromSpinGroup = setAbund - else if (this%xctInit) then - this%xct%getAbundanceFromSpinGroup = setAbund + if (this%calculatorInit) then + this%calculator%getAbundanceFromSpinGroup = setAbund end if end subroutine @@ -327,14 +277,8 @@ module CrossSectionCalcDriver_M real(kind=8)::emin,emax integer::num - if (this%mlbwInit) then - call this%mlbw%setRange(emin, emax, num) - else if (this%artificalInit) then - call this%artifical%setRange(emin, emax, num) - else if (this%croInit) then - call this%cro%setRange(emin, emax, num) - else if (this%xctInit) then - call this%xct%setRange(emin, emax, num) + if (this%calculatorInit) then + call this%calculator%setRange(emin, emax, num) end if end subroutine @@ -342,14 +286,8 @@ module CrossSectionCalcDriver_M class(CrossSectionCalcDriver) :: this value = .false. - if (this%mlbwInit) then - value = this%mlbw%wantDerivs - else if (this%artificalInit) then - value = this%artifical%wantDerivs - else if (this%croInit) then - value = this%cro%wantDerivs - else if (this%xctInit) then - value = this%xct%wantDerivs + if (this%calculatorInit) then + value = this%calculator%wantDerivs end if end function @@ -358,14 +296,8 @@ module CrossSectionCalcDriver_M value = 0 - if (this%mlbwInit) then - value = this%mlbw%covariance%getNumTotalParam() - else if (this%artificalInit) then - value = this%artifical%covariance%getNumTotalParam() - else if (this%croInit) then - value = this%cro%covariance%getNumTotalParam() - else if (this%xctInit) then - value = this%xct%covariance%getNumTotalParam() + if (this%calculatorInit) then + value = this%calculator%covariance%getNumTotalParam() end if end function @@ -382,18 +314,9 @@ module CrossSectionCalcDriver_M call this%crossPerSpin%initialize() instance_ptr =this%crossPerSpin%instance_ptr end if - if (this%mlbwInit) then - this%mlbw%wantCrossPerSpin = want - this%mlbw%crossPerSpin%instance_ptr = instance_ptr - else if (this%artificalInit) then - this%artifical%wantCrossPerSpin = want - this%artifical%crossPerSpin%instance_ptr = instance_ptr - else if (this%croInit) then - this%cro%wantCrossPerSpin = want - this%cro%crossPerSpin%instance_ptr = instance_ptr - else if (this%xctInit) then - this%xct%wantCrossPerSpin = want - this%xct%crossPerSpin%instance_ptr = instance_ptr + if (this%calculatorInit) then + this%calculator%wantCrossPerSpin = want + this%calculator%crossPerSpin%instance_ptr = instance_ptr end if end subroutine end module CrossSectionCalcDriver_M diff --git a/sammy/src/the/CrossSectionCalculator_M.f90 b/sammy/src/the/CrossSectionCalculator_M.f90 index 5ccbf0536..fd4aea11a 100644 --- a/sammy/src/the/CrossSectionCalculator_M.f90 +++ b/sammy/src/the/CrossSectionCalculator_M.f90 @@ -69,6 +69,7 @@ module CrossSectionCalculator_M procedure, pass(this) :: setRange => CrossSectionCalculator_setRange ! set the range and reserve enough space in crossData (the latter for efficiency only) procedure, pass(this) :: initialize => CrossSectionCalculator_initialize procedure, pass(this) :: destroy => CrossSectionCalculator_destroy + procedure, pass(this) :: calcCross => CrossSectionCalculator_calcCross end type CrossSectionCalculator contains @@ -150,6 +151,25 @@ subroutine CrossSectionCalculator_setWantDeriv(this, wantDerivs) end if end subroutine +subroutine CrossSectionCalculator_calcCross(this, ener, Ipoten) + class(CrossSectionCalculator) :: this + real(kind=8)::ener + integer::ipoten + + integer::itot + + + itot = this%covariance%getNumTotalParam() + 1 + if ( .not.this%wantDerivs) itot = 1 + call this%crossData%reserveColumns(this%row, itot) + + this%ener = ener + + this%enerSq = ener + IF (this%ener.LT.0.0d0) this%enerSq = -this%enerSq + if (this%enerSq.gt.0.0d0) this%enerSq = dSQRT(this%enerSq) +end subroutine + ! ! For a given spin group, determine the number of varied parameters ! (including their resonance and channel. -- GitLab