Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

This question already has an answer here:

I want to numerically integrate function berrycur over kx and ky. The definition of berrycur is given at the end of the question. The plot of berrycur[kx,ky,1] is shown as follows:

enter image description here

and numerical integration

NIntegrate[
 berrycur[kx, ky, 1], {kx, -((2 \π)/Sqrt[3]), (2 \π)/Sqrt[3]}, {ky, 0, (4 \π)/3}]

gives error message

NIntegrate::slwcon: Numerical integration converging too slowly; suspect one of the following: singularity, value of the integration is 0, highly oscillatory integrand, or WorkingPrecision too small. >>

The correct answer should be zero. Since the function is abnormal at some places, the error message is forgivable.

Then I define another function berrycurtmp which is

berrycursum[kx_?NumericQ, ky_?NumericQ] = 
 berrycur[kx, ky, 1] + berrycur[kx, ky, 2]

the plot of berrycursum is smooth now as shown in

enter image description here

But the numerical integration

NIntegrate[
     berrycur[kx, ky, 1], {kx, -((2 \π)/Sqrt[3]), (2 \π)/Sqrt[3]}, {ky, 0, (4 \π)/3}]

still gives error message

NIntegrate::slwcon: Numerical integration converging too slowly; suspect one of the following: singularity, value of the integration is 0, highly oscillatory integrand, or WorkingPrecision too small. >>

why? And how could we get the correct answer zero?? And how to speed up this numerical integration?


The definition of berrycur is here

Clear[h]
h[kx_, ky_] := {{0.01` + 
     0.1` (-4 Cos[1.5` ky] Sin[0.8660254037844386` kx] + 
        2 Sin[1.7320508075688772` kx]), 
    1 + 2 Cos[0.8660254037844386` kx] Cos[1.5` ky] - 
     2 I Cos[0.8660254037844386` kx] Sin[1.5` ky], 0, 
    0}, {1 + 2 Cos[0.8660254037844386` kx] Cos[1.5` ky] + 
     2 I Cos[0.8660254037844386` kx] Sin[1.5` ky], -0.01` - 
     0.1` (-4 Cos[1.5` ky] Sin[0.8660254037844386` kx] + 
        2 Sin[1.7320508075688772` kx]), 0, 0}, {0, 0, 
    0.01` - 0.1` (-4 Cos[1.5` ky] Sin[0.8660254037844386` kx] + 
        2 Sin[1.7320508075688772` kx]), 
    1 + 2 Cos[0.8660254037844386` kx] Cos[1.5` ky] - 
     2 I Cos[0.8660254037844386` kx] Sin[1.5` ky]}, {0, 0, 
    1 + 2 Cos[0.8660254037844386` kx] Cos[1.5` ky] + 
     2 I Cos[0.8660254037844386` kx] Sin[1.5` ky], -0.01` + 
     0.1` (-4 Cos[1.5` ky] Sin[0.8660254037844386` kx] + 
        2 Sin[1.7320508075688772` kx])}};
dim = Length@h[1, 1];

Clear[hpar1, hpar2];
hpar1[kx_, ky_] = D[h[kx, ky], kx];
hpar2[kx_, ky_] = D[h[kx, ky], ky];

Clear[purifyeigs];
purifyeigs[eigs_] := 
  Transpose@Sort@Transpose@{Re[eigs[[1]]], eigs[[2]]};

berrycur[kxkx_?NumericQ, kyky_?NumericQ, i_] := Module[{eigs},
  eigs = purifyeigs@Eigensystem[h[kxkx, kyky]];
  Im@Sum[((Conjugate[eigs[[2, i]]].hpar1[kxkx, kyky].eigs[[2, 
           j]])*(Conjugate[eigs[[2, j]]].hpar2[kxkx, kyky].eigs[[2, 
           i]]) - (Conjugate[eigs[[2, i]]].hpar2[kxkx, kyky].eigs[[2, 
           j]])*(Conjugate[eigs[[2, j]]].hpar1[kxkx, kyky].eigs[[2, 
           i]]))/(eigs[[1, i]] - eigs[[1, j]])^2, {j, 
     DeleteCases[Range[1, dim], i]}]]
share|improve this question

marked as duplicate by Jens, Öskå, rasher, bobthechemist, acl Jun 27 at 12:42

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1 Answer 1

up vote 8 down vote accepted

It's numeric integration. So it has no means of "knowing" the correct result is zero. In the process error estimates will be formed and if they are larger than the estimated result, this is a problem. But of course they must be larger since the actual result is zero.

The way to tame this is to specify an AccuracyGoal that is attainable using the given precision of the input. That way NIntegrate might be convinced to give up gracefully once error estimates show the accuracy (in the sense of Mathematica's documentation for Accuracy, that is, number of correct digits to right of decimal point) has been attained.

NIntegrate[berrycur[kx, ky, 1], {kx, -((2 \[Pi])/Sqrt[3]), (2 \[Pi])/Sqrt[3]},
 {ky, 0, (4 \[Pi])/3}, AccuracyGoal -> 12]

(* Out[352]= -3.80551771684*10^-14 *)
share|improve this answer
    
Thank you very much! AccuracyGoal works perfectly –  matheorem Jun 26 at 23:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.