Esempio n. 1
0
void CLOP_sub::genpu(const Epetra_IntVector *LD, 
		     const Epetra_MultiVector *Coords, double rhs[], 
		     double sol[], double temp[], int atype_sub, int ndim_sub,
		     double WORK[], int LWORK, double Edof_sub[],
		     int & nneg)
{
  int i, j, k, nrhs, nnz_rhs, dof;
  double *coords;
  atype = atype_sub;
  ndim = ndim_sub;
  LD->ExtractView(&locdof);
  int ndof_proc = Coords->Stride();
  Coords->ExtractView(&coords, &ndof_proc);
  x = &coords[0];
  y = &coords[ndof_proc];
  z = &coords[2*ndof_proc];
  xcent = 0; ycent = 0; zcent = 0;
  for (i=0; i<ndof; i++) {
    dof = subdofs[i]; xcent += x[dof]; ycent += y[dof]; zcent += z[dof];
  }
  xcent /= ndof; ycent /= ndof; zcent /= ndof;
  if (atype == 1) {
    csdim_max = 1;
    nrhs = ndim + 1;
    nnz_rhs = ndof*nrhs;
    myzero(rhs, nnz_rhs);
    if (ndim == 2) {
      for (i=0; i<ndof; i++) {
	dof = subdofs[i];
	rhs[i+0*ndof] = 1;
	rhs[i+1*ndof] = x[dof] - xcent;
	rhs[i+2*ndof] = y[dof] - ycent;
      }
    }
    if (ndim == 3) {
      for (i=0; i<ndof; i++) {
	dof = subdofs[i];
	rhs[i+0*ndof] = 1;
	rhs[i+1*ndof] = x[dof] - xcent;
	rhs[i+2*ndof] = y[dof] - ycent;
	rhs[i+3*ndof] = z[dof] - zcent;
      }
    }
    //
    // check to make sure coordinate data is meaningful
    //
    int coord_flag = 0;
    for (i=0; i<ndof; i++) {
      dof = subdofs[i];
      if (x[dof] != 0) {
	coord_flag = 1;
        break;
      }
    }
    if (coord_flag == 0) nrhs = 1;
  }
  if (atype == 2) {
    if (ndim == 2) {
      csdim_max = 3;
      nrhs = 6;
      nnz_rhs = ndof*nrhs;
      myzero(rhs, nnz_rhs);
      for (i=0; i<ndof; i++) {
	dof = subdofs[i];
	if (abs(locdof[dof]) == 1) {
	  rhs[i+0*ndof] = 1;
	  rhs[i+1*ndof] = x[dof] - xcent;
	  rhs[i+2*ndof] = y[dof] - ycent;
	}
	if (abs(locdof[dof]) == 2) {
	  rhs[i+3*ndof] = 1;
	  rhs[i+4*ndof] = x[dof] - xcent;
	  rhs[i+5*ndof] = y[dof] - ycent;
	}
      }
    }
    if (ndim == 3) {
      csdim_max = 6;
      nrhs = 12;
      nnz_rhs = ndof*nrhs;
      if (ndof < nrhs) nnz_rhs = nrhs*nrhs;
      myzero(rhs, nnz_rhs);
      for (i=0; i<ndof; i++) {
	dof = subdofs[i];
	if (abs(locdof[dof]) == 1) {
	  rhs[i+0*ndof] = 1;
	  rhs[i+1*ndof] = x[dof] - xcent;
	  rhs[i+2*ndof] = y[dof] - ycent;
	  rhs[i+3*ndof] = z[dof] - zcent;
	}
	if (abs(locdof[dof]) == 2) {
	  rhs[i+4*ndof] = 1;
	  rhs[i+5*ndof] = x[dof] - xcent;
	  rhs[i+6*ndof] = y[dof] - ycent;
	  rhs[i+7*ndof] = z[dof] - zcent;
	}
	if (abs(locdof[dof]) == 3) {
	  rhs[i+8*ndof]  = 1;
	  rhs[i+9*ndof]  = x[dof] - xcent;
	  rhs[i+10*ndof] = y[dof] - ycent;
	  rhs[i+11*ndof] = z[dof] - zcent;
	}
      }
    }
  }
  if (atype == 3) {
    csdim_max = 3;
    nrhs = 9;
    nnz_rhs = ndof*nrhs;
    if (ndof < nrhs) nnz_rhs = nrhs*nrhs;
    myzero(rhs, nnz_rhs);
    for (i=0; i<ndof; i++) {
      dof = subdofs[i];
      if (abs(locdof[dof]) == 1) {
	rhs[i+0*ndof] = 1;
	rhs[i+1*ndof] = x[dof] - xcent;
	rhs[i+2*ndof] = y[dof] - ycent;
      }
      if (abs(locdof[dof]) == 2) {
	rhs[i+3*ndof] = 1;
	rhs[i+4*ndof] = x[dof] - xcent;
	rhs[i+5*ndof] = y[dof] - ycent;
      }
      if (abs(locdof[dof]) == 3) {
	rhs[i+6*ndof] = 1;
	rhs[i+7*ndof] = x[dof] - xcent;
	rhs[i+8*ndof] = y[dof] - ycent;
      }
    }
  }
  A_sub->sol(nrhs, rhs, sol, temp);
  //
  // form SOL' * K * SOL = SOL' * RHS
  //
  char TRANSA = 'T'; char TRANSB = 'N';
  double ALPHA = 1, BETA = 0;
  Epetra_BLAS EB;
  if (ndof == 0) {
    Edof = new double[0];
    int duma1(0), duma2;
    Comm->MaxAll(&duma1, &duma2, 1);
    return;
  }
  EB.GEMM(TRANSA, TRANSB, nrhs, nrhs, ndof, ALPHA,
	  sol, ndof, rhs, ndof, BETA, temp, nrhs);
  //
  // eigenvalues of SOL' * K * SOL are positive if K is positive, but
  // may be negative if K has one or more negative eigenvalues. check
  // the signs of eigenvalues of SOL' * K * SOL and make zero if
  // any are found to be negative
  //
  char JOBZ('V'), UPLO('U');
  double S[60];
  for (i=0; i<nrhs*nrhs; i++) rhs[i] = temp[i];
  DSYEV_F77(&JOBZ, &UPLO, &nrhs, temp, &nrhs, S, WORK, &LWORK, &INFO, 1, 1);
  assert(INFO == 0);
  nneg = 0;
  double max_mag(0), tol_neg_eig(1e-8);
  for (i=0; i<nrhs; i++) if (fabs(S[i]) > max_mag) max_mag = fabs(S[i]);
  for (i=0; i<nrhs; i++) if (S[i] < -tol_neg_eig*max_mag) nneg++;
  if (nneg > 0) {
    myzero(rhs, nrhs*nrhs);
    for (i=0; i<nrhs; i++) {
      if (S[i] > tol_neg_eig*max_mag) {
	for (j=0; j<nrhs; j++) {
	  for (k=0; k<nrhs; k++) rhs[j+nrhs*k] += 
				   S[i]*temp[i*nrhs+j]*temp[i*nrhs+k];
	}
      }
    }
  }
  for (i=0; i<nrhs*nrhs; i++) temp[i] = rhs[i];
  //
  // calculate pseudo-inverse
  //
  double RCOND = 1e-8;
  int RANK;
  double rhs_sol[60], sol_sol[60];
  myzero(rhs, nrhs*nrhs);
  for (i=0; i<nrhs; i++) rhs[i*(nrhs+1)] = 1;
  DGELSS_F77(&nrhs, &nrhs, &nrhs, temp, &nrhs, rhs, &nrhs, S, &RCOND, &RANK,
	     WORK, &LWORK, &INFO);
  assert(INFO == 0);
  //
  // calculate diagonal of flexibility matrix
  //
  Edof = new double[ndof];
  TRANSA = 'N';
  double Edof_max(0), tol_Edof(1e-8);
  for (i=0; i<ndof; i++) {
    for (j=0; j<nrhs; j++) sol_sol[j] = sol[i+j*ndof];
    EB.GEMV(TRANSA, nrhs, nrhs, ALPHA, rhs, nrhs,
	    sol_sol, BETA, rhs_sol);
    Edof[i] = EB.DOT(nrhs, sol_sol, rhs_sol);
    if (Edof[i] > Edof_max) Edof_max = Edof[i];
    //    assert(Edof[i] >= 0);
  }
  for (i=0; i<ndof; i++) {
    if (Edof[i] < tol_Edof*Edof_max) Edof[i] = tol_Edof*Edof_max;
    Edof_sub[subdofs[i]] += Edof[i];
  }
  /*
  if (MyPID == 0) {
    cout << "xcent, ycent = " << xcent << " " << ycent << endl;
    cout << "singular values = " << endl;
    for (i=0; i<nrhs; i++) cout << S[i] << endl;
    //    cout << "x, y, Edof_orig" << endl;
    //    for (i=0; i<ndof; i++) {
    //      cout << x[dofa[i]] << " " << y[dofa[i]] << " " << Edof[i] << endl;
    //    }
  }
  */
}
Esempio n. 2
0
//=============================================================================
void Epetra_LAPACK::SYEV(const char JOBZ, const char UPLO, const int N, double* A, const int LDA, double* W, double* WORK, const int LWORK, int* INFO) const{

  DSYEV_F77(CHAR_MACRO(JOBZ), CHAR_MACRO(UPLO), &N, A, &LDA, W, WORK, &LWORK, INFO);

}