Beispiel #1
0
//---------------------------------------------------------
void xyztorst
(
  const DVec& X,  // [in]
  const DVec& Y,  // [in]
  const DVec& Z,  // [in]
        DVec& r,  // [out]
        DVec& s,  // [out]
        DVec& t   // [out]
)
//---------------------------------------------------------
{
  // function [r,s,t] = xyztorst(x, y, z)
  // Purpose : Transfer from (x,y,z) in equilateral tetrahedron
  //           to (r,s,t) coordinates in standard tetrahedron

  double sqrt3=sqrt(3.0), sqrt6=sqrt(6.0); int Nc=X.size();
  DVec v1(3),v2(3),v3(3),v4(3);
  DMat tmat1(3,Nc), A(3,3), rhs; 
  
  v1(1)=(-1.0);  v1(2)=(-1.0/sqrt3);  v1(3)=(-1.0/sqrt6);
  v2(1)=( 1.0);  v2(2)=(-1.0/sqrt3);  v2(3)=(-1.0/sqrt6);
  v3(1)=( 0.0);  v3(2)=( 2.0/sqrt3);  v3(3)=(-1.0/sqrt6);
  v4(1)=( 0.0);  v4(2)=( 0.0      );  v4(3)=( 3.0/sqrt6);

  // back out right tet nodes
  tmat1.set_row(1,X); tmat1.set_row(2,Y); tmat1.set_row(3,Z);
  rhs = tmat1 - 0.5*outer(v2+v3+v4-v1, ones(Nc));
  A.set_col(1,0.5*(v2-v1)); A.set_col(2,0.5*(v3-v1)); A.set_col(3,0.5*(v4-v1));

  DMat RST = A|rhs;

  r=RST.get_row(1); s=RST.get_row(2); t=RST.get_row(3);
}
Beispiel #2
0
// DGESV uses the LU factorization to compute solution 
// to a real system of linear equations, A * X = B, 
// where A is square (N,N) and X, B are (N,NRHS).
//
// If the system is over or under-determined, 
// (i.e. A is not square), then pass the problem
// to the Least-squares solver (DGELSS) below.
//---------------------------------------------------------
void umSOLVE(const DMat& mat, const DMat& B, DMat& X)
//---------------------------------------------------------
{
  if (!mat.ok()) {umWARNING("umSOLVE()", "system is empty"); return;}
  if (!mat.is_square()) {
    umSOLVE_LS(mat, B, X);    // return a least-squares solution.
    return;
  }

  DMat A(mat);    // work with copy of input
  X = B;          // initialize result with RHS

  int rows=A.num_rows(), LDA=A.num_rows(), cols=A.num_cols();
  int LDB=B.num_rows(), NRHS=B.num_cols(), info=0;
  if (rows<1) {umWARNING("umSOLVE()", "system is empty"); return;}
  IVec ipiv(rows);

  // Solve the system.
  GESV(rows, NRHS, A.data(), LDA, ipiv.data(), X.data(), LDB, info);

  if (info < 0) { 
    X = 0.0;
    umERROR("umSOLVE(A,B, X)", 
            "Error in input argument (%d)\nNo solution computed.", -info);
  } else if (info > 0) {
    X = 0.0;
    umERROR("umSOLVE(A,B, X)", 
            "\nINFO = %d.  U(%d,%d) was exactly zero."
            "\nThe factorization has been completed, but the factor U is "
            "\nexactly singular, so the solution could not be computed.", 
              info, info, info);
  }
}
Beispiel #3
0
// DPOSV uses Cholesky factorization A=U^T*U, A=L*L^T 
// to compute the solution to a real system of linear 
// equations A*X=B, where A is a square, (N,N) symmetric 
// positive definite matrix and X and B are (N,NRHS).
//
// If the system is over or under-determined, 
// (i.e. A is not square), then pass the problem
// to the Least-squares solver (DGELSS) below.
//---------------------------------------------------------
void umSOLVE_CH(const DMat& mat, const DMat& B, DMat& X)
//---------------------------------------------------------
{
  if (!mat.ok()) {umWARNING("umSOLVE_CH()", "system is empty"); return;}
  if (!mat.is_square()) {
    umSOLVE_LS(mat, B, X);    // return a least-squares solution.
    return;
  }
  
  DMat A(mat);    // Work with a copy of input array.
  X = B;          // initialize solution with rhs

  int rows=A.num_rows(), LDA=A.num_rows(), cols=A.num_cols();
  int LDB=X.num_rows(), NRHS=X.num_cols(), info=0;
  assert(LDB >= rows);  // enough space for solutions?

  // Solve the system.
  POSV('U', rows, NRHS, A.data(), LDA, X.data(), LDB, info);

  if (info < 0) { 
    X = 0.0;
    umERROR("umSOLVE_CH(A,B, X)", 
            "Error in input argument (%d)\nNo solution computed.", -info);
  } else if (info > 0) {
    X = 0.0;
    umERROR("umSOLVE_CH(A,B, X)", 
            "\nINFO = %d.  The leading minor of order %d of A"
            "\nis not positive definite, so the factorization" 
            "\ncould not be completed. No solution computed.", 
              info, info);
  }
}
Beispiel #4
0
//---------------------------------------------------------
DMat& chol(DMat& A, bool in_place)
//---------------------------------------------------------
{
  // Given symmetric positive-definite matrix A,
  // return its Cholesky-factorization for use
  // later in solving (multiple) linear systems.

  int M=A.num_rows(), LDA=A.num_rows(), info=0;
  char uplo = 'U';

  if (in_place) 
  {
    // factorize arg
    POTRF (uplo, M, A.data(), LDA, info);
    if (info) { umERROR("chol(A)", "dpotrf reports: info = %d", info); }
    A.zero_below_diag();
    A.set_factmode(FACT_CHOL);  // indicate factored state
    return A;
  } 
  else
  {
    // factorize copy of arg
    DMat* tmp = new DMat(A, OBJ_temp, "chol(A)");
    POTRF (uplo, M, tmp->data(), LDA, info);
    if (info) { umERROR("chol(A)", "dpotrf reports: info = %d", info); }
    tmp->zero_below_diag();
    tmp->set_factmode(FACT_CHOL);  // indicate factored state
#if (0)
    // compare with Matlab
    tmp->print(g_MSGFile, "chol", "lf", 4, 8);
#endif
    return (*tmp);
  }
}
Beispiel #5
0
// compute eigensystem of a real symmetric matrix
//---------------------------------------------------------
void eig_sym(const DMat& A, DVec& ev, DMat& Q, bool bDoEVecs)
//---------------------------------------------------------
{
  if (!A.is_square()) { umERROR("eig_sym(A)", "matrix is not square."); }

  int N = A.num_rows();
  int LDA=N, LDVL=N, LDVR=N, ldwork=10*N, info=0;
  DVec work(ldwork, 0.0, OBJ_temp, "work_TMP");

  Q = A;          // Calculate eigenvectors in Q (optional)
  ev.resize(N);   // Calculate eigenvalues in ev

  char jobV = bDoEVecs ? 'V' : 'N';

  SYEV (jobV,'U', N, Q.data(), LDA, ev.data(), work.data(), ldwork, info);  

  if (info < 0) { 
    umERROR("eig_sym(A, Re,Im)", "Error in input argument (%d)\nNo solution computed.", -info);
  } else if (info > 0) {
    umLOG(1, "eig_sym(A, W): ...\n"
             "\nthe algorithm failed to converge;"
             "\n%d off-diagonal elements of an intermediate"
             "\ntridiagonal form did not converge to zero.\n", info);
  }
}
Beispiel #6
0
//---------------------------------------------------------
DMat& lu(DMat& A, bool in_place)
//---------------------------------------------------------
{
  // Given square matrix A, return its lu-factorization 
  // for use later in solving (multiple) linear systems.

  if (!A.is_square()) { umERROR("lu(A)", "matrix is not square."); }
  int rows=A.num_rows(); int N=rows, LDA=rows, info=0;
  int* ipiv = umIVector(rows);

  if (in_place) 
  {
    // factorize arg
    GETRF(N, N, A.data(), LDA, ipiv, info);
    if (info) { umERROR("lu(A)", "dgetrf reports: info = %d", info); }
    A.set_pivots(ipiv);        // store pivots
    A.set_factmode(FACT_LUP);  // indicate factored state
    return A;
  } 
  else
  {
    // factorize copy of arg
    DMat* tmp = new DMat(A, OBJ_temp, "lu(A)");
    GETRF(N, N, tmp->data(), LDA, ipiv, info);
    if (info) { umERROR("lu(A)", "dgetrf reports: info = %d", info); }
    tmp->set_pivots(ipiv);        // store pivots
    tmp->set_factmode(FACT_LUP);  // indicate factored state
    return (*tmp);
  }
}
Beispiel #7
0
//---------------------------------------------------------
DMat& qr(DMat& A, bool in_place)
//---------------------------------------------------------
{
  // Form orthogonal QR factorization of A(m,n). 
  // The result Q is represented as a product of 
  // min(m, n) elementary reflectors. 

  int M=A.num_rows(), N=A.num_cols(), LDA=A.num_rows();
  int min_mn = A.min_mn(), info=0; DVec tau(min_mn);

  if (in_place) 
  {
    // factorize arg
    GEQRF(M, N, A.data(), LDA, tau.data(), info);

    if (info) { umERROR("qr(A)", "dgeqrf reports: info = %d", info); }
  //A.set_qrtau(tau);         // H(i) = I - tau * v * v'
    A.set_factmode(FACT_QR);  // indicate factored state
    return A;
  } 
  else
  {
    // factorize copy of arg
    DMat* tmp = new DMat(A, OBJ_temp, "qr(A)");
    GEQRF (M, N, tmp->data(), LDA, tau.data(), info);

    if (info) { umERROR("qr(A)", "dgeqrf reports: info = %d", info); }
  //tmp->set_qrtau(tau);         // H(i) = I - tau * v * v'
    tmp->set_factmode(FACT_QR);  // indicate factored state
    return (*tmp);
  }
}
Beispiel #8
0
// DPOSV uses Cholesky factorization A=U^T*U, A=L*L^T 
// to compute the solution to a real system of linear 
// equations A*X=B, where A is a square, (N,N) symmetric 
// positive definite matrix and X and B are (N,NRHS).
//---------------------------------------------------------
void umSOLVE_CH(const DMat& mat, const DVec& b, DVec& x)
//---------------------------------------------------------
{
  // check args
  assert(mat.is_square());            // symmetric
  assert(b.size() >= mat.num_rows()); // is b consistent?
  assert(b.size() <= x.size());       // can x store solution?
  
  DMat A(mat);    // work with copy of input
  x = b;          // allocate solution vector

  int rows=A.num_rows(), LDA=A.num_rows(), cols=A.num_cols();
  int  LDB=b.size(), NRHS=1, info=0;
  if (rows<1) {umWARNING("umSOLVE_CH()", "system is empty"); return;}

  // Solve the system.
  POSV('U', rows, NRHS, A.data(), LDA, x.data(), LDB, info);

  if (info < 0) { 
    x = 0.0;
    umERROR("umSOLVE_CH(A,b, x)", 
            "Error in input argument (%d)\nNo solution computed.", -info);
  } else if (info > 0) {
    x = 0.0;
    umERROR("umSOLVE_CH(A,b, x)", 
            "\nINFO = %d.  The leading minor of order %d of A"
            "\nis not positive definite, so the factorization" 
            "\ncould not be completed. No solution computed.", 
              info, info);
  }
}
Beispiel #9
0
 void scalarMultInPlace(DMat<RT>& A, const typename RT::ElementType &f)
 {
   for (size_t i=0; i<A.numRows()*A.numColumns(); i++)
     {
       A.ring().mult(A.array()[i], f, A.array()[i]);
     }
 }
Beispiel #10
0
bool isZero(const DMat<RT>& A)
{
  size_t len = A.numRows() * A.numColumns();
  if (len == 0) return true;
  for (auto t = A.array() + len - 1; t >= A.array(); t--)
    if (!A.ring().is_zero(*t)) return false;
  return true;
}
Beispiel #11
0
 void negateInPlace(DMat<RT>& A)
 // A = -A
 {
   size_t len = A.numRows() * A.numColumns();
   for (size_t i=0; i<len; i++)
     {
       A.ring().negate(A.array()[i], A.array()[i]);
     }
 }
Beispiel #12
0
//---------------------------------------------------------
void Euler3D::CouetteBC3D
(
    const DVec& xi,
    const DVec& yi,
    const DVec& zi,
    const DVec& nxi,
    const DVec& nyi,
    const DVec& nzi,
    const IVec& tmapI,
    const IVec& tmapO,
    const IVec& tmapW,
    const IVec& tmapC,
    double ti,
    DMat& Qio
)
//---------------------------------------------------------
{
    //#######################################################
    // FIXME: what about top and bottom of 3D annulus?
    //#######################################################


    // gmapB = concat(mapI,mapO,mapW, ...);
    // Check for no boundary faces
    if (gmapB.size() < 1) {
        return;
    }

    // function [Q] = CouetteBC3D(xin, yin, nxin, nyin, mapI, mapO, mapW, mapC, Q, time);
    // Purpose: evaluate solution for Couette flow

    // Couette flow (mach .2 at inner cylinder)
    // gamma = 1.4;

    int Nr = Qio.num_rows();
    DVec rho,rhou,rhov,rhow,Ener;

    // wrap current state data (columns of Qio)
    rho.borrow (Nr, Qio.pCol(1));
    rhou.borrow(Nr, Qio.pCol(2));
    rhov.borrow(Nr, Qio.pCol(3));
    rhow.borrow(Nr, Qio.pCol(4));
    Ener.borrow(Nr, Qio.pCol(5));

    // update boundary nodes of Qio with boundary data
    // pre-calculated in function precalc_bdry_data()

    rho (gmapB) = rhoB;
    rhou(gmapB) = rhouB;
    rhov(gmapB) = rhovB;
    rhow(gmapB) = rhowB;
    Ener(gmapB) = EnerB;
}
Beispiel #13
0
//---------------------------------------------------------
void CurvedINS2D::Report(bool bForce)
//---------------------------------------------------------
{
  static DMat vort;
  bool normal_report=true;
  if (eVolkerCylinder == sim_type) {normal_report=false;}

#if (1)
  normal_report=true;
#endif

  // print report header on first step
  if (1 == tstep) {
    if (normal_report) {
      umLOG(1, "\n  step    time      min(Ux)    max(Ux)   min(Vort)    max(Vort)\n"
                 "--------------------------------------------------------------------\n");
    } else {
      umLOG(1, "\n  step     time        Cd/ra      Cl/ra       dP   \n"
                 "---------------------------------------------------\n");
    }
  }

  if (normal_report) {
    if (!umMOD(tstep,Nreport)||(1==tstep)||(tstep==Nsteps)||bForce) {

      Curl2D(Ux, Uy, vort);

      umLOG(1, "%7d  %6.3lf  %10.5lf %10.5lf  %10.2lf %10.2lf\n", 
               tstep, time, Ux.min_val(), Ux.max_val(), vort.min_val(), vort.max_val());
    }
  } else {
    // VolkerCylinder: compute coefficients of drag and lift,
    // as well as the pressure drop at the two sample points.
    INSLiftDrag2D(0.05);
  }


  if (!umMOD(tstep,Nrender)||(1==tstep)||(tstep==Nsteps)||bForce) 
  {
    // (this->*ExactSolution)(x, y, time, nu, exUx, exUy, exPR);

    Curl2D(Ux, Uy, vort);

    // load render data
    Q_plot.set_col(1, Ux); // -exUx);
    Q_plot.set_col(2, Uy); // -exUy);
    Q_plot.set_col(3, PR); // -exPR);
    Q_plot.set_col(4, vort);

    OutputVTK(Q_plot, NvtkInterp);
  }
}
Beispiel #14
0
inline void norm2(const DMat<RT>& M, size_t n, typename RT::RealElementType& result)
{
  const auto& C = M.ring();
  const auto& R = C.real_ring();
  typename RT::RealElementType c;
  R.init(c);
  R.set_zero(result);
  for(size_t i=0; i<n; i++) {
    C.abs_squared(c,M.entry(0,i));
    R.add(result,result,c);
  }
  R.clear(c);
}
Beispiel #15
0
 void set(DMat<RT>& A, MatrixWindow wA, const DMat<RT>& B, MatrixWindow wB)
 {
   M2_ASSERT(wA.sameSize(wB));
   long rA = wA.begin_row;
   long rB = wB.begin_row;
   for ( ; rA < wA.end_row; ++rA, ++rB)
     {
       long cA = wA.begin_column;
       long cB = wB.begin_column;
       for ( ; cA < wA.end_column; ++cA, ++cB)
         A.ring().set(A.entry(rA,cA), B.entry(rB,cB));
     }
 }
Beispiel #16
0
   void scalarMultInPlace(DMat<RT>& A, MatrixWindow wA, const typename RT::ElementType& c)
 {
   M2_ASSERT(wA.sameSize(wB));
   long rA = wA.begin_row;
   for ( ; rA < wA.end_row; ++rA)
     {
       long cA = wA.begin_column;
       for ( ; cA < wA.end_column; ++cA)
         {
           auto& a = A.entry(rA,cA);
           A.ring().mult(a, a, c);
         }
     }
 }
Beispiel #17
0
   void scalarMult(DMat<RT>& A, MatrixWindow wA, const typename RT::ElementType& c, const DMat<RT>& B, MatrixWindow wB)
 {
   M2_ASSERT(wA.sameSize(wB));
   long rA = wA.begin_row;
   long rB = wB.begin_row;
   for ( ; rA < wA.end_row; ++rA, ++rB)
     {
       long cA = wA.begin_column;
       long cB = wB.begin_column;
       for ( ; cA < wA.end_column; ++cA, ++cB)
         {
           A.ring().mult(A.entry(rA,cA), c, B.entry(rB,cB));
         }
     }
 }
Beispiel #18
0
void addTo(DMat<RT>& A, MatrixWindow wA, const DMat<RT>& B, MatrixWindow wB)
{
  assert(wA.sameSize(wB));
  long rA = wA.begin_row;
  long rB = wB.begin_row;
  for (; rA < wA.end_row; ++rA, ++rB)
    {
      long cA = wA.begin_column;
      long cB = wB.begin_column;
      for (; cA < wA.end_column; ++cA, ++cB)
        {
          auto& a = A.entry(rA, cA);
          A.ring().add(a, a, B.entry(rB, cB));
        }
    }
}
Beispiel #19
0
//---------------------------------------------------------
void CurvedCNS2D::BoxFlowIC2D
(
  const DVec&   xi,   // [in]
  const DVec&   yi,   // [in]
        double  ti,   // [in]
        DMat&   Qo    // [out]
)
//---------------------------------------------------------
{
  // function Q = BoxFlowIC2D(x, y, time)
  //
  // Purpose: compute plane flow configuration 

  //-------------------------------------
  // adjust parameters
  //-------------------------------------
  this->gamma = 1.4;
  this->gm1   = 0.4;  // (gamma-1)

  //-------------------------------------
  // use wrappers to update Qo in-place
  //-------------------------------------
  DVec rho,rhou,rhov,Ener; int Nr=Np*K;
  rho.borrow (Nr, Qo.pCol(1));
  rhou.borrow(Nr, Qo.pCol(2));
  rhov.borrow(Nr, Qo.pCol(3));
  Ener.borrow(Nr, Qo.pCol(4));

  if (1) 
  {
    this->pref = 12.0;

    rho  =  1.0;
    rhou = -sin(2.0*pi*y);
    rhov =  sin(4.0*pi*x);
    Ener = pref/gm1 + 0.5*(sqr(rhou) + sqr(rhov)).dd(rho);
  } 
  else 
  {
    this->pref = 12.0;

    rho  = 1.0;
    rhou = 0.0;
    rhov = 0.0;
    Ener = pref/gm1 + 0.5 * rho.dm(exp(-4.0*(sqr(cos(pi*x))+sqr(cos(pi*y)))));
  }
}
Beispiel #20
0
void transpose(const DMat<RT>& A, DMat<RT>& result)
{
  assert(&A != &result);  // these cannot be aliased!
  assert(result.numRows() == A.numColumns());
  assert(result.numColumns() == A.numRows());
  for (size_t c = 0; c < A.numColumns(); ++c)
    {
      auto i = A.columnBegin(c);
      auto j = result.rowBegin(c);
      auto end = A.columnEnd(c);
      for (; i != end; ++i, ++j) A.ring().set(*j, *i);
    }
}
Beispiel #21
0
engine_RawArrayIntPairOrNull rawLQUPFactorizationInPlace(MutableMatrix *A, M2_bool transpose)
{
#ifdef HAVE_FFLAS_FFPACK
  // Suppose A is m x n
  // then we get A = LQUP = LSP, see e.g. http://www.ens-lyon.fr/LIP/Pub/Rapports/RR/RR2006/RR2006-28.pdf
  // P and Q are permutation info using LAPACK's convention:, see
  // http://www.netlib.org/lapack/explore-html/d0/d39/_v_a_r_i_a_n_t_s_2lu_2_r_e_c_2dgetrf_8f.html
  // P is n element permutation on column: size(P)=min(m,n); 
  // for 1 <= i <= min(m,n), col i of the  matrix was interchanged with col P(i).
  // Qt is m element permutation on rows (inverse permutation)
  // for 1 <= i <= min(m,n), col i of the  matrix was interchanged with col P(i).
  A->transpose();

  DMat<M2::ARingZZpFFPACK> *mat = A->coerce< DMat<M2::ARingZZpFFPACK> >();
  if (mat == 0) 
    {
      throw exc::engine_error("LUDivine not defined for this ring");
      //      ERROR("LUDivine not defined for this ring");
      //      return 0;
    }
  size_t nelems = mat->numColumns();
  if (mat->numRows() < mat->numColumns()) nelems = mat->numRows();
 

  std::vector<size_t> P(nelems, -1);
  std::vector<size_t> Qt(nelems, -1);
  
  // ignore return value (rank) of:
  LUdivine(mat->ring().field(),
                       FFLAS::FflasNonUnit,
                       (transpose ? FFLAS::FflasTrans : FFLAS::FflasNoTrans),
                       mat->numRows(),
                       mat->numColumns(),
                       mat->array(),
                       mat->numColumns(),
                       &P[0], 
                       &Qt[0]);

  engine_RawArrayIntPairOrNull result = new engine_RawArrayIntPair_struct;
  result->a = stdvector_to_M2_arrayint(Qt);
  result->b = stdvector_to_M2_arrayint(P);

  return result;
#endif
  return 0;
}
//---------------------------------------------------------
DMat& NDG2D::CurvedDGJump2D
(
  const DMat& gU,     // [in]
  const IVec& gmapD,  // [in]
  const DVec& bcU     // [in]
)
//---------------------------------------------------------
{
  // function [jumpU] = CurvedDGJump2D(gU, gmapD, bcU)
  // purpose: compute discontinuous Galerkin jump applied
  //          to a field given at cubature and Gauss nodes

  DMat mmCHOL;  DVec gUM,gUP,fx;
  DMat *tmp = new DMat("jumpU", OBJ_temp);
  DMat &jumpU(*tmp);

  // shorthand references
  Cub2D& cub = this->m_cub; Gauss2D& gauss = this->m_gauss;

  // surface traces at Gauss nodes
  gUM = gU(gauss.mapM);
  gUP = gU(gauss.mapP);
  if (gmapD.size()>0) { gUP(gmapD) = bcU(gmapD); }

  // compute jump term and lift to triangle interiors
  fx = gUM - gUP;
  jumpU = -gauss.interpT*(gauss.W.dm(fx));

  // multiply straight sided triangles by inverse mass matrix
  jumpU(All,straight) = VVT * dd(jumpU(All,straight), J(All,straight));

  // multiply by custom inverse mass matrix for each curvilinear triangle
  int Ncurved = curved.size(), k=0;
  for (int m=1; m<=Ncurved; ++m) {
    k = curved(m);
    mmCHOL.borrow(Np,Np, cub.mmCHOL.pCol(k));
    mmCHOL.set_factmode(FACT_CHOL);  // indicate factored state
    jumpU(All,k) = chol_solve(mmCHOL, jumpU(All,k));
  }

  // these parameters may be OBJ_temp (allocated on the fly)
  if (OBJ_temp == gU.get_mode())  { delete (&gU); }
  if (OBJ_temp == bcU.get_mode()) { delete (&bcU); }

  return jumpU;
}
Beispiel #23
0
//---------------------------------------------------------
void eig(const DMat& A, DVec& Re, DMat& VL, DMat& VR, bool bL, bool bR)
//---------------------------------------------------------
{
  // Compute eigensystem of a real general matrix
  // Currently NOT returning imaginary components

  static DMat B;

  if (!A.is_square()) { umERROR("eig(A)", "matrix is not square."); }

  int N = A.num_rows();
  int LDA=N, LDVL=N, LDVR=N, ldwork=10*N, info=0;

  Re.resize(N);     // store REAL components of eigenvalues in Re
  VL.resize(N,N);   // storage for LEFT eigenvectors
  VR.resize(N,N);   // storage for RIGHT eigenvectors
  DVec Im(N);     // NOT returning imaginary components
  DVec work(ldwork, 0.0);

  // Work on a copy of A
  B = A;

  char jobL = bL ? 'V' : 'N';   // calc LEFT eigenvectors?
  char jobR = bR ? 'V' : 'N';   // calc RIGHT eigenvectors?

  GEEV (jobL,jobR, N, B.data(), LDA, Re.data(), Im.data(), 
        VL.data(), LDVL, VR.data(), LDVR, work.data(), ldwork, info);

  if (info < 0) { 
    umERROR("eig(A, Re,Im)", "Error in input argument (%d)\nNo solution computed.", -info);
  } else if (info > 0) {
    umLOG(1, "eig(A, Re,Im): ...\n"
             "\nThe QR algorithm failed to compute all the"
             "\neigenvalues, and no eigenvectors have been" 
             "\ncomputed;  elements %d+1:N of WR and WI contain"
             "\neigenvalues which have converged.\n", info);
  }

#if (0)
  // Return (Re,Imag) parts of eigenvalues as columns of Ev
  Ev.resize(N,2);
  Ev.set_col(1, Re);
  Ev.set_col(2, Im);
#endif

#ifdef _DEBUG
    //#####################################################
    // Check for imaginary components in eigenvalues
    //#####################################################
    double im_max = Im.max_val_abs();
    if (im_max > 1e-6) {
      umERROR("eig(A)", "imaginary components in eigenvalues.");
    }
    //#####################################################
#endif
}
Beispiel #24
0
//---------------------------------------------------------
bool lu_solve(DMat& LU, const DMat& B, DMat& X)
//---------------------------------------------------------
{
  // Solve a set of linear systems using lu-factored square matrix.
  try {
    LU.solve_LU(B, X, false, false);
  } catch(...) { return false; }
  return true;
}
// tex "table" output
//---------------------------------------------------------
void textable
(
  string&   capt, 
  FILE*     fid, 
  string*   titles, 
  DMat&     entries, 
  string*   form
)
//---------------------------------------------------------
{
  int Nrows=entries.num_rows(), Ncols=entries.num_cols(), n=0,m=0;
  
  fprintf(fid, "\\begin{table} \n");
  fprintf(fid, "\\caption{%s} \n", capt.c_str());

  fprintf(fid, "\\begin{center} \n");
  fprintf(fid, "\\begin{tabular}{|");
  for (n=1; n<=Ncols; ++n) {
    fprintf(fid, "c|");
    if (2==n) {
      fprintf(fid, "|");
    }
  }
  fprintf(fid, "} \\hline \n ");

  for (n=1; n<=(Ncols-1); ++n) {
    fprintf(fid, "%s & ", titles[n].c_str());
  }
  fprintf(fid, " %s \\\\ \\hline \n ", titles[Ncols].c_str());

  for (m=1; m<=Nrows; ++m) {
    for (n=1; n<=(Ncols-1); ++n) {
      fprintf(fid, form[n].c_str(), entries(m,n)); fprintf(fid, " & ");
    }
    if (m<Nrows) {
      fprintf(fid, form[Ncols].c_str(), entries(m,Ncols)); fprintf(fid, " \\\\ \n ");
    } else {
      fprintf(fid, form[Ncols].c_str(), entries(m,Ncols)); fprintf(fid, " \\\\ \\hline \n ");
    }
  }
  fprintf(fid, "\\end{tabular} \n");
  fprintf(fid, "\\end{center} \n"); 
  fprintf(fid, "\\end{table} \n");
}
//---------------------------------------------------------
void CurvedINS2D::BackdropIC2D
(
  const DVec&   xi, 
  const DVec&   yi, 
        double  ti,   // [in]
        double  nu,   // [in]
        DMat&   Uxo,  // [out]
        DMat&   Uyo,  // [out]
        DMat&   PRo   // [out]
)
//---------------------------------------------------------
{
  // function [Ux, Uy, PR] = BackdropIC2D(x, y, time, nu)
  // Purpose: evaluate solution for "Backdrop" configuration

  Uxo.fill(0.0);
  Uyo.fill(0.0);
  PRo.fill(0.0);
}
Beispiel #27
0
inline void lowdegreesweep(DMat& m, size_t i, DynamicVector<NodeEliminationStatus>& status) {
    bool hasLowDegreeNeighbour = false;
    /* Cerco vicini low-degree*/
    for (size_t j = 0; j < m.rows(); ++j) {
        if (j != i && status[j] == LOW_DEGREE) {
            hasLowDegreeNeighbour = true;
            status[i] = NOT_ELIMINATED;
            break;
        }
    }
    /* Se non aveva un vicino low_degree allora è lui il nodo low_degree!*/
    if (!hasLowDegreeNeighbour) {
        status[i] = LOW_DEGREE;
        for (size_t j = 0; j < m.rows(); ++j) {

            if (j != i)
                status[j] = NOT_ELIMINATED;
        }
    }
}
Beispiel #28
0
 inline M2_arrayintOrNull rankProfile(const DMat<RT>& A, 
                                      bool row_profile)
 {
   std::vector<size_t> profile;
   if (row_profile)
     {
       // First transpose A
       DMat<RT> B(A.ring(), A.numColumns(), A.numRows());
       MatrixOps::transpose(A,B);
       DMatLinAlg<RT> LUdecomp(B);
       LUdecomp.columnRankProfile(profile);
       return stdvector_to_M2_arrayint(profile);
     }
   else
     {
       DMatLinAlg<RT> LUdecomp(A);
       LUdecomp.columnRankProfile(profile);
       return stdvector_to_M2_arrayint(profile);
     }
 }
//---------------------------------------------------------
void EulerShock2D::Report(bool bForce)
//---------------------------------------------------------
{
  CurvedEuler2D::Report(bForce);

  if (tstep>=1 && tstep <= resid.size()) 
  {
    // calculate residual
    // resid(tstep) = sqrt(sum(sum(sum((Q-oldQ).^2)))/(4*K*Np));
    // resid(tstep) = sqrt(sum(sum(sum((Q-oldQ).^2)))/(4*K*Np))/dt;


    DMat Qresid = sqr(Q-oldQ); double d4KNp = double(4*K*Np);
    resid(tstep) = sqrt(Qresid.sum()/d4KNp);

    if (eScramInlet == sim_type) {
      // scale residual
      resid(tstep) /= dt;
    }
  }
}
Beispiel #30
0
inline void eliminationOperators(DMat& A, DynamicVector<size_t>& Cset, size_t fnode,
        DynamicVector<double>& q, SpMat& P, size_t& P_col, size_t P_row) {
    double scalingFactor = 1.0;
    P.reserve(P_row, A.nonZeros(fnode) - 1);
    DynamicVector<size_t>::Iterator ccol = Cset.begin();
    for (size_t frow = 0; frow < A.rows(); ++frow) {
        if (frow == fnode) { //Elemento sulla diagonale
            q[P_row] = (1.0 / A(frow, fnode));
            scalingFactor = -(q[P_row]);
        } else if (ccol != Cset.end()) {
            break; //Non ha senso andare avanti se abbiamo finito i ccol
        } else if (frow == (*ccol)) {
            P.append(P_row, P_col, A(frow, fnode));
            P_col++;
            ccol++;
        }
    }
    P.finalize(P_row);

    for (SpMat::Iterator it = P.begin(P_row); it != P.end(P_row); it++)
        it->value() *= -scalingFactor;
}