Beispiel #1
0
// Calculate U_{2}/N = 1/N \sum_k (\omega_+(k) + \mu_b) n_b(\omega_+(k))
func PairEnergy(env *tempAll.Environment) (float64, error) {
	// find omega_+ coefficients
	a, b := env.A, env.B
	if !env.FixedPairCoeffs || !env.PairCoeffsReady {
		plusCoeffs, err := OmegaFit(env, OmegaPlus)
		if err != nil {
			fmt.Println("suppressing error in PairEnergy - cannot find pair spectrum")
			return 0.0, nil
		}
		a, b = plusCoeffs[0], plusCoeffs[2]
	}
	// kz^2 version - incompatible with finite magnetic field
	if env.PairKzSquaredSpectrum && math.Abs(env.Be_field) < 1e-9 {
		integrand := func(y float64) float64 {
			num := math.Pow(y, 1.5)
			denom := math.Exp(y-env.Beta*env.Mu_b) - 1.0
			return num / denom
		}
		integral, err := OmegaIntegralY(env, a, b, integrand)
		if err != nil {
			return 0.0, err
		}
		return integral / math.Pow(env.Beta, 2.5), nil
	}
	// cos(kz) version
	if math.Abs(env.Be_field) < 1e-9 {
		integrand := func(y, kz float64) float64 {
			bterm := 2.0 * b * (1.0 - math.Cos(kz))
			num := y/env.Beta + bterm
			denom := math.Exp(y+env.Beta*(bterm-env.Mu_b)) - 1.0
			return num / denom
		}
		integral, err := OmegaIntegralCos(env, a, b, integrand)
		if err != nil {
			return 0.0, err
		}
		return integral, nil
	}
	// if we get here, math.Abs(env.Be_field) >= 1e-9
	//fmt.Printf("about to calculate E2 B sum for env = %s\n", env.String())
	E2BSumTerm := func(ri int) float64 {
		r := float64(ri)
		I0 := bessel.ModifiedBesselFirstKindZeroth(2.0 * b * env.Beta * r)
		I1 := bessel.ModifiedBesselFirstKindFirst(2.0 * b * env.Beta * r)
		omega_c := 4.0 * env.Be_field * a
		mu_tilde := env.Mu_b - omega_c/2.0
		expL := math.Exp(r * env.Beta * (mu_tilde - 2.0*b))
		expR := math.Exp(-env.Beta * omega_c * r)
		expm1 := -math.Expm1(-env.Beta * omega_c * r)
		return expL * ((I0*(0.5+2.0*b)-2.0*b*I1)*expm1 + (I0 * omega_c * expR * expm1 * expm1))
	}
	sum, _ := seriesaccel.Levin_u(E2BSumTerm, 1, 20)
	// reporting of absErr:
	// (dropped this since absErr is always very small compared to sum)
	//sum, absErr := seriesaccel.Levin_u(E2BSumTerm, 1, 20)
	//fmt.Printf("env=%s; E2 B sum %e, absErr %e\n", env.String(), sum, absErr)
	return 2.0 * env.Be_field * sum / math.Pi, nil
}
Beispiel #2
0
// Magnetization per unit area divided by e
func Magnetization(env *tempAll.Environment) (float64, error) {
	if math.Abs(env.Be_field) < 1e-9 {
		return 0.0, nil
	}
	if -env.Mu_b > -2.0*env.Mu_h {
		return 0.0, nil
	}
	// find omega_+ coefficients
	a, b := env.A, env.B
	if !env.FixedPairCoeffs || !env.PairCoeffsReady {
		plusCoeffs, err := OmegaFit(env, OmegaPlus)
		//fmt.Printf("plusCoeffs in Magnetization: %v\n", plusCoeffs)
		if err != nil {
			fmt.Println("suppressing error in magnetization - cannot find pair spectrum")
			return 0.0, nil
		}
		a, b = plusCoeffs[0], plusCoeffs[2]
	}
	MSumTerm := func(ri int) float64 {
		r := float64(ri)
		I0 := bessel.ModifiedBesselFirstKindZeroth(2.0 * b * env.Beta * r)
		omega_c := 4.0 * env.Be_field * a
		mu_tilde := env.Mu_b - omega_c/2.0
		exp := -math.Expm1(-r * env.Beta * omega_c)
		bracket := 1.0/(env.Beta*r*exp) - omega_c*math.Exp(-r*env.Beta*omega_c)/(exp*exp)
		return I0 * math.Exp(r*env.Beta*(mu_tilde-2.0*b)) * bracket
		/*
			bracket_num_term := func(ni int) float64 {
				n := float64(ni)
				nm1_fact := math.Gamma(n)
				return -math.Pow(-r * env.Beta * omega_c, n + 1.0) / ((n + 1.0) * nm1_fact)
			}
			bracket_denom_term := func(ni int) float64 {
				n := float64(ni)
				n_fact := math.Gamma(n + 1.0)
				return math.Pow(-r * env.Beta * omega_c, n) * (math.Pow(2.0, n - 1.0) - 1.0) / n_fact
			}
			bracket_num, _ := seriesaccel.Levin_u(bracket_num_term, 1, 20)
			bracket_denom, _ := seriesaccel.Levin_u(bracket_denom_term, 2, 20)
			return I0 * math.Exp(r*env.Beta*(mu_tilde-2.0*b)) * bracket_num / (2.0 * bracket_denom)
		*/
	}
	//sum, absErr := seriesaccel.Levin_u(MSumTerm, 1, 20)
	//fmt.Printf("Magnetization sum %e, absErr %e\n", sum, absErr)
	sum, _ := seriesaccel.Levin_u(MSumTerm, 1, 20)
	x2, err := X2(env)
	if err != nil {
		return 0.0, err
	}
	return -a*x2 + sum/math.Pi, nil
	//return -a*x2 - sum/math.Pi, nil
}
Beispiel #3
0
// Concentration of paired holons
func X2(env *tempAll.Environment) (float64, error) {
	// kz^2 version - incompatible with finite magnetic field
	if env.PairKzSquaredSpectrum && math.Abs(env.Be_field) < 1e-9 {
		nu, err := nu(env)
		if err != nil {
			return 0.0, err
		}
		x2 := nu / math.Pow(env.Beta, 3.0/2.0)
		return x2, nil
	}
	// cos(kz) version
	if -env.Mu_b > -2.0*env.Mu_h {
		return 0.0, nil
	}
	// find omega_+ coefficients
	a, b := env.A, env.B
	if !env.FixedPairCoeffs || !env.PairCoeffsReady {
		plusCoeffs, err := OmegaFit(env, OmegaPlus)
		//fmt.Printf("plusCoeffs in X2: %v\n", plusCoeffs)
		if err != nil {
			fmt.Println("suppressing error in x2 - cannot find pair spectrum")
			return 0.0, nil
		}
		a, b = plusCoeffs[0], plusCoeffs[2]
	}
	// zero magnetic field with cos(kz) spectrum
	if math.Abs(env.Be_field) < 1e-9 {
		integrand := func(y, kz float64) float64 {
			bterm := 2.0 * b * (1.0 - math.Cos(kz))
			return 2.0 / (math.Exp(y+env.Beta*(bterm-env.Mu_b)) - 1.0)
		}
		plus, err := OmegaIntegralCos(env, a, b, integrand)
		if err != nil {
			return 0.0, err
		}
		return plus, nil
	}
	// if we get here, math.Abs(env.Be_field) >= 1e-9
	//fmt.Printf("about to calculate x2 sum for env = %s\n", env.String())
	x2BSumTerm := func(ri int) float64 {
		r := float64(ri)
		I0 := bessel.ModifiedBesselFirstKindZeroth(2.0 * b * env.Beta * r)
		omega_c := 4.0 * env.Be_field * a
		mu_tilde := env.Mu_b - omega_c/2.0
		return I0 * math.Exp(env.Beta*r*(mu_tilde-2.0*b)) / (-math.Expm1(-env.Beta * omega_c * r))
		/*
			sum_n_term := func(ni int) float64 {
				n := float64(ni)
				np1_fact := math.Gamma(n + 2.0)
				return math.Pow(-r * env.Beta * omega_c, n) / np1_fact
			}
			sum_n, _ := seriesaccel.Levin_u(sum_n_term, 1, 20)
			return I0 * math.Exp(env.Beta*r*(mu_tilde-2.0*b)) / (r * (1.0 + sum_n))
		*/
	}
	sum, _ := seriesaccel.Levin_u(x2BSumTerm, 1, 20)
	//fmt.Printf("%v\n", sum)
	// reporting of absErr:
	// (dropped this since absErr is always very small relative to sum)
	//sum, absErr := seriesaccel.Levin_u(x2BSumTerm, 1, 20)
	//fmt.Printf("for env=%s; x2 B sum %e, absErr %e\n", env.String(), sum, absErr)
	return 2.0 * env.Be_field * sum / math.Pi, nil
	//return sum / (2.0 * math.Pi * env.Beta * a), nil
}