std::shared_ptr<Matrix> MultiExcitonHamiltonian<VecType>::compute_offdiagonal_1e(const DSubSpace& AB, const DSubSpace& ApBp, std::shared_ptr<const Matrix> hAB) const { Coupling term_type = coupling_type(AB,ApBp); GammaSQ operatorA; GammaSQ operatorB; int neleA = AB.template ci<0>()->det()->nelea() + AB.template ci<0>()->det()->neleb(); switch(term_type) { case Coupling::aET : operatorA = GammaSQ::CreateAlpha; operatorB = GammaSQ::AnnihilateAlpha; break; case Coupling::inv_aET : operatorA = GammaSQ::AnnihilateAlpha; operatorB = GammaSQ::CreateAlpha; --neleA; break; case Coupling::bET : operatorA = GammaSQ::CreateBeta; operatorB = GammaSQ::AnnihilateBeta; break; case Coupling::inv_bET : operatorA = GammaSQ::AnnihilateBeta; operatorB = GammaSQ::CreateBeta; --neleA; break; default : return std::make_shared<Matrix>(AB.dimerstates(), ApBp.dimerstates()); } Matrix gamma_A = *gammaforest_->template get<0>(AB.offset(), ApBp.offset(), operatorA); Matrix gamma_B = *gammaforest_->template get<1>(AB.offset(), ApBp.offset(), operatorB); Matrix tmp = gamma_A * (*hAB) ^ gamma_B; auto out = std::make_shared<Matrix>(AB.dimerstates(), ApBp.dimerstates()); reorder_matrix(tmp.data(), out->data(), AB.template nstates<0>(), ApBp.template nstates<0>(), AB.template nstates<1>(), ApBp.template nstates<1>()); if ( (neleA % 2) == 1 ) out->scale(-1.0); return out; }
std::shared_ptr<Matrix> MultiExcitonHamiltonian<VecType>::couple_blocks(DSubSpace& AB, DSubSpace& ApBp) { Coupling term_type = coupling_type(AB, ApBp); DSubSpace* space1 = &AB; DSubSpace* space2 = &ApBp; bool flip = (static_cast<int>(term_type) < 0); if (flip) { term_type = Coupling(-1*static_cast<int>(term_type)); std::swap(space1,space2); } std::shared_ptr<Matrix> out; switch(term_type) { case Coupling::none : out = std::make_shared<Matrix>(space1->dimerstates(), space2->dimerstates()); break; case Coupling::diagonal : out = compute_inter_2e(*space1, *space2); break; case Coupling::aET : out = compute_aET(*space1, *space2); break; case Coupling::bET : out = compute_bET(*space1, *space2); break; case Coupling::abFlip : out = compute_abFlip(*space1, *space2); break; case Coupling::abET : out = compute_abET(*space1, *space2); break; case Coupling::aaET : out = compute_aaET(*space1, *space2); break; case Coupling::bbET : out = compute_bbET(*space1, *space2); break; default : throw std::logic_error("Asking for a coupling type that has not been written."); } if (flip) out = out->transpose(); return out; }
InputParameters validParams<PorousFlowFullySaturatedMassTimeDerivative>() { InputParameters params = validParams<TimeKernel>(); MooseEnum coupling_type("Hydro ThermoHydro HydroMechanical ThermoHydroMechanical", "Hydro"); params.addParam<MooseEnum>("coupling_type", coupling_type, "The type of simulation. For simulations involving Mechanical " "deformations, you will need to supply the correct Biot coefficient. " "For simulations involving Thermal flows, you will need an associated " "ConstantThermalExpansionCoefficient Material"); params.addRangeCheckedParam<Real>( "biot_coefficient", 1.0, "biot_coefficient>=0 & biot_coefficient<=1", "Biot coefficient"); params.addParam<bool>("multiply_by_density", true, "If true, then this Kernel is the time derivative of the fluid " "mass. If false, then this Kernel is the derivative of the " "fluid volume (which is common in poro-mechanics)"); params.addRequiredParam<UserObjectName>( "PorousFlowDictator", "The UserObject that holds the list of Porous-Flow variable names."); params.addClassDescription("Fully-saturated version of the single-component, single-phase fluid " "mass derivative wrt time"); return params; }
void ASDSpinMap<VecType>::couple_blocks(const DimerSubspace<VecType>& AB, const DimerSubspace<VecType>& ApBp) { const Coupling term_type = coupling_type(AB, ApBp); auto spin_block = std::make_shared<Matrix>(AB.dimerstates(), ApBp.dimerstates()); if ( (term_type == Coupling::abFlip) || (term_type == Coupling::baFlip) ) { std::shared_ptr<VecType> SAp, SBp; std::shared_ptr<const VecType> A = AB.template ci<0>(); std::shared_ptr<const VecType> B = AB.template ci<1>(); switch (term_type) { case Coupling::abFlip : SAp = ApBp.template ci<0>()->spin_lower(A->det()); SBp = ApBp.template ci<1>()->spin_raise(B->det()); break; case Coupling::baFlip : SAp = ApBp.template ci<0>()->spin_raise(A->det()); SBp = ApBp.template ci<1>()->spin_lower(B->det()); break; default: assert(false); break; // Control should never be able to reach here... } const int nA = AB.template nstates<0>(); const int nB = AB.template nstates<1>(); const int nAp = ApBp.template nstates<0>(); const int nBp = ApBp.template nstates<1>(); std::vector<double> AdotAp, BdotBp; for (int iAp = 0; iAp < nAp; ++iAp) { for (int iA = 0; iA < nA; ++iA) { AdotAp.push_back(SAp->data(iAp)->dot_product(*A->data(iA))); } } for (int iBp = 0; iBp < nBp; ++iBp) { for (int iB = 0; iB < nB; ++iB) { BdotBp.push_back(SBp->data(iBp)->dot_product(*B->data(iB))); } } for (int iBp = 0; iBp < nBp; ++iBp) { for (int iAp = 0; iAp < nAp; ++iAp) { const int iABp = ApBp.dimerindex(iAp,iBp); int iAB = 0; for (int iB = 0; iB < nB; ++iB) { for (int iA = 0; iA < nA; ++iA, ++iAB) { spin_block->element(iAB,iABp) += AdotAp[iA+ nA*iAp] * BdotBp[iB + nB*iBp]; } } } } const int n = spin_block->ndim(); const int m = spin_block->mdim(); const int ioff = AB.offset(); const int joff = ApBp.offset(); for (int ispin = 0; ispin < n; ++ispin) { for (int jspin = 0; jspin < m; ++jspin) { const double ele = spin_block->element(ispin, jspin); if ( std::fabs(ele) > 1.0e-4) { this->emplace(std::make_pair(ispin + ioff, jspin + joff), ele); this->emplace(std::make_pair(jspin + joff, ispin + ioff), ele); } } } } }