lambda2.h

📄 View in API Reference (Doxygen) · View on basilisk.fr

Examples (4): bubble, isotropic, sphere, tangaroa

static void eigsrt (double d[dimension],
		    double v[dimension][dimension])
{
  int k, j, i;
  double p;

  for (i = 0; i < dimension - 1; i++) {
    p = d[k = i];

    for (j = i + 1; j < dimension; j++)
      if (d[j] >= p) 
	p = d[k = j];
    if (k != i) {
      d[k] = d[i];
      d[i] = p;
      for (j = 0; j < dimension; j++) {
	p = v[j][i];
	v[j][i] = v[j][k];
	v[j][k] = p;
      }
    }
  }
}

#define ROTATE(a,i,j,k,l) {\
    g=a[i][j];h=a[k][l];a[i][j]=g-s*(h+g*tau);a[k][l]=h+s*(g-h*tau);}

*

void eigenvalues (double a[dimension][dimension],
		  double d[dimension],
		  double v[dimension][dimension])
{
  int j, iq, ip, i;
  double tresh, theta, tau, t, sm, s, h, g, c, b[dimension], z[dimension];

  for (ip = 0; ip < dimension; ip++) {
    for (iq = 0; iq < dimension; iq++)
      v[ip][iq] = 0.0;
    v[ip][ip] = 1.0;
  }

  for (ip = 0; ip < dimension; ip++) {
    b[ip] = d[ip] = a[ip][ip];
    z[ip] = 0.0;
  }

  for (i = 1; i <= 50; i++) {
    sm = 0.0;
    for (ip = 0; ip < dimension - 1; ip++) {
      for (iq = ip + 1; iq < dimension; iq++)
	sm += fabs (a[ip][iq]);
    }
    if (sm == 0.0) {
      eigsrt (d, v);
      return;
    }
    if (i < 4)
      tresh = 0.2*sm/(dimension*dimension);
    else
      tresh = 0.0;
    for (ip = 0; ip < dimension - 1; ip++) {
      for (iq = ip + 1; iq < dimension; iq++) {
	g = 100.0*fabs (a[ip][iq]);
	if (i > 4 && fabs(d[ip]) + g == fabs(d[ip]) &&
	    fabs(d[iq]) + g == fabs(d[iq]))
	  a[ip][iq] = 0.0;
	else if (fabs (a[ip][iq]) > tresh) {
	  h = d[iq] - d[ip];
	  if (fabs(h) + g == fabs(h))
	    t = a[ip][iq]/h;
	  else {
	    theta = 0.5*h/a[ip][iq];
	    t = 1.0/(fabs (theta) + sqrt (1.0 + theta*theta));
	    if (theta < 0.0) t = -t;
	  }
	  c = 1.0/sqrt (1 + t*t);
	  s = t*c;
	  tau = s/(1.0 + c);
	  h = t*a[ip][iq];
	  z[ip] -= h;
	  z[iq] += h;
	  d[ip] -= h;
	  d[iq] += h;
	  a[ip][iq] = 0.0;
	  for (j = 0; j <= ip - 1; j++)
	    ROTATE (a, j, ip, j, iq);
	  for (j = ip + 1; j <= iq - 1; j++)
	    ROTATE (a, ip, j, j, iq);
	  for (j = iq + 1; j < dimension; j++)
	    ROTATE(a, ip, j, iq, j);
	  for (j = 0; j < dimension; j++)
	    ROTATE(v, j, ip, j, iq);
	}
      }
    }
    for (ip = 0; ip < dimension; ip++) {
      b[ip] += z[ip];
      d[ip] = b[ip];
      z[ip] = 0.0;
    }
  }
  /* Too many iterations */
  for (i = 0; i < dimension; i++) {
    for (j = 0; j < dimension; j++)
      fprintf (stderr, "%10.3g ", a[i][j]);
    fprintf (stderr, "\n");
  }
  assert (false);
}

void lambda2 (const vector u, scalar l2)
{
  foreach() {
    double JJ[dimension][dimension];
    scalar s = u.x;
    int i = 0;
    foreach_dimension()
      JJ[0][i++] = center_gradient (s);
    s = u.y; i = 0;
    foreach_dimension()
      JJ[1][i++] = center_gradient (s);
    s = u.z; i = 0;
    foreach_dimension()
      JJ[2][i++] = center_gradient (s);
    double S2O2[dimension][dimension];
    for (int i = 0; i < dimension; i++)
      for (int j = 0; j < dimension; j++) {
	S2O2[i][j] = 0.;
	for (int k = 0; k < dimension; k++)
	  S2O2[i][j] += JJ[i][k]*JJ[k][j] + JJ[k][i]*JJ[j][k];
      }
    double lambda[dimension], ev[dimension][dimension];
    eigenvalues (S2O2, lambda, ev);
    l2[] = lambda[1]/2.;
  }
}