Exemplo n.º 1
0
/** factrs

  For symmetric structure, transforms submatricies to form
  matricies of the symmetric modes and calls routine to LU decompose
  matricies.
  
  If no symmetry [nrow = np], the routine is called to LU decompose the
  complete matrix.
*/
void factrs(nec_output_file& s_output,  int64_t np, int64_t nrow, complex_array& a, int_array& ip )
{
  DEBUG_TRACE("factrs(" << np << "," << nrow << ")");
  if (nrow == np) { // no symmetry
    lu_decompose(s_output,  np, a, ip, nrow );
    return;
  }
  
  int num_symmetric_modes = nrow / np;
  DEBUG_TRACE("\tnum_symmetric_modes = " << num_symmetric_modes);
  
  for (int mode = 0; mode < num_symmetric_modes; mode++ ) {
    int64_t mode_offset = mode * np;
    
    complex_array a_temp = a.segment(mode_offset, a.size()-mode_offset);
    int_array ip_temp = ip.segment(mode_offset, ip.size()-mode_offset);
    
    lu_decompose(s_output,  np, a_temp, ip_temp, nrow );
  }
}
Exemplo n.º 2
0
/**
  Subroutine solves, for symmetric structures, handles the
  transformation of the right hand side vector and solution
  of the matrix eq.
  \param neq number of equations?
  \param nrh dimension of right hand  vector?
*/
void solves(complex_array& a, int_array& ip, complex_array& b, int64_t neq,
      int64_t nrh, int64_t np, int64_t n, int64_t mp, int64_t m, int64_t nop, 
      complex_array& symmetry_array)
{
  DEBUG_TRACE("solves(" << neq << "," << nrh << "," << np << "," << n << ")");
  DEBUG_TRACE("      ( nop=" << nop << ")");
  
  /* Allocate some scratch memory */
  complex_array scm;
  scm.resize(n + 2*m);
  
  int npeq= np+ 2*mp;
  nec_float fnop = nop;
  nec_float fnorm = 1.0/ fnop;
  int nrow= neq;
  
  if ( nop != 1) {
    for (int ic = 0; ic < nrh; ic++ ) {
      int64_t column_offset = ic*neq;
      if ( (n != 0) && (m != 0) ) {
        for (int i = 0; i < neq; i++ )
          scm[i]= b[i+column_offset];

        int j= np-1;

        for (int k = 0; k < nop; k++ ) {
          if ( k != 0 ) {
            int ia= np-1;
            for (int i = 0; i < np; i++ ) {
              ia++;
              j++;
              b[j+column_offset]= scm[ia];
            }

            if ( k == (nop-1) )
              continue;
          } /* if ( k != 0 ) */
  
          int mp2 = 2*mp;
          int ib= n-1;
          for (int i = 0; i < mp2; i++ ) {
            ib++;
            j++;
            b[j+column_offset]= scm[ib];
          }
        } /* for( k = 0; k < nop; k++ ) */
      } /* if ( (n != 0) && (m != 0) ) */

      /* transform matrix eq. rhs vector according to symmetry modes */
      for (int i = 0; i < npeq; i++ ) {
        for (int k = 0; k < nop; k++ ) {
          int64_t ia= i+ k* npeq;
          scm[k]= b[ia+column_offset];
        }

        nec_complex sum_normal(scm[0]);
        for (int k = 1; k < nop; k++ )
          sum_normal += scm[k];

        b[i+column_offset]= sum_normal * fnorm;

        for (int k = 1; k < nop; k++ ) {
          int ia= i+ k* npeq;
          nec_complex sum(scm[0]);
  
          for (int j = 1; j < nop; j++ )
            sum += scm[j]* conj( symmetry_array[k+j*nop]);
  
          b[ia+column_offset]= sum* fnorm;
        }
      } /* for( i = 0; i < npeq; i++ ) */
    } /* for( ic = 0; ic < nrh; ic++ ) */
  } /* if ( nop != 1) */

  /* solve each mode equation */
  for (int kk = 0; kk < nop; kk++ ) {
    int ia= kk* npeq;

    for (int ic = 0; ic < nrh; ic++ ) {
      int column_offset = ic*neq;
      complex_array a_sub = a.segment(ia, a.size()-ia);
      complex_array b_sub = b.segment(ia+column_offset, b.size() - (ia+column_offset) );
      int_array ip_sub = ip.segment(ia, ip.size()-ia);
      solve( npeq, a_sub, ip_sub, b_sub, nrow );
    }
  } /* for( kk = 0; kk < nop; kk++ ) */
  
  if ( nop == 1) {
    return;
  }
  
  /* inverse transform the mode solutions */
  for (int ic = 0; ic < nrh; ic++ ) {
    int column_offset = ic*neq;
    for (int i = 0; i < npeq; i++ ) {
      for (int k = 0; k < nop; k++ ) {
        int ia= i+ k* npeq;
        scm[k]= b[ia+column_offset];
      }

      nec_complex sum_normal(scm[0]);
      for (int k = 1; k < nop; k++ )
        sum_normal += scm[k];

      b[i+column_offset]= sum_normal;
      
      for (int k = 1; k < nop; k++ ) {
        int ia= i+ k* npeq;
        
        nec_complex sum(scm[0]);

        for (int j = 1; j < nop; j++ )
          sum += scm[j]* symmetry_array[k+j*nop];

        b[ia+column_offset]= sum;
      }
    } /* for( i = 0; i < npeq; i++ ) */

    if ( (n == 0) || (m == 0) )
      continue;

    for (int i = 0; i < neq; i++ )
            scm[i]= b[i+column_offset];

    int j = np-1;

    for (int32_t k = 0; k < nop; k++ ) {
      if ( k != 0 )  {
        int ia = np-1;
        for (int32_t i = 0; i < np; i++ ) {
          ia++;
          j++;
          b[ia+column_offset]= scm[j];
        }

        if ( k == nop)
          continue;
      } /* if ( k != 0 ) */

      int ib = n-1;
      int mp2 = 2* mp;
      for (int i = 0; i < mp2; i++ ) {
        ib++;
        j++;
        b[ib+column_offset]= scm[j];
      }
    } /* for( k = 0; k < nop; k++ ) */
  } /* for( ic = 0; ic < nrh; ic++ ) */
}