예제 #1
0
파일: icprecond.C 프로젝트: vivianyw/oofem
void
CompCol_ICPreconditioner :: ICSolve(FloatArray &dest) const
{
    int i, t, M = dest.giveSize();
    FloatArray work(M);
    double val;
    // lower diag

    work.zero();
    // solve Uw=x
    for ( i = 0; i < M; i++ ) {
        work(i) = val = ( dest(i) + work(i) ) / val_( pntr_(i) );
        for ( t = pntr_(i) + 1; t < pntr_(i + 1); t++ ) {
            work( indx_(t) ) -= val_(t) * val;
        }
    }

    dest.zero();
    // solve U^Ty=w
    for ( i = M - 1; i >= 0; i-- ) {
        for ( t = pntr_(i) + 1; t < pntr_(i + 1); t++ ) {
            dest(i) -= val_(t) * dest( indx_(t) );
        }

        dest(i) = ( work(i) + dest(i) ) / val_( pntr_(i) );
    }
}
예제 #2
0
void SymCompCol :: times(const FloatArray &x, FloatArray &answer) const
{
    int M = dim_ [ 0 ];
    int N = dim_ [ 1 ];

    //      Check for compatible dimensions:
    if ( x.giveSize() != N ) {
        OOFEM_ERROR("SymCompCol::times: Error in CompCol -- incompatible dimensions");
    }

    answer.resize(M);
    answer.zero();

    int j, t;
    double rhs, sum;

    for ( j = 0; j < N; j++ ) {
        rhs = x(j);
        sum = 0.0;
        for ( t = colptr_(j) + 1; t < colptr_(j + 1); t++ ) {
            answer( rowind_(t) ) += val_(t) * rhs; // column loop
            sum += val_(t) * x( rowind_(t) ); // row loop
        }

        answer(j) += sum;
        answer(j) += val_( colptr_(j) ) * rhs; // diagonal
    }
}
예제 #3
0
void luaStore_writeValue(TValue * v, file& f, std::vector<void *>& functions)
{
	uint i;
	bool found;
	byte type = ttype(v);

	f.write(type);

	switch(type)
	{
	case LUA_TNIL: // nil has no data
		break;
	case LUA_TBOOLEAN:
		f.write((byte)val_(v).b);
		break;
	case LUA_TLIGHTUSERDATA: // write the pointer
		f.write(&val_(v).p, sizeof(void*));
		break;
	case LUA_TNUMBER:
		f.write(num_(v));
		break;
	case LUA_TSTRING: // write the pointer to gc objects
	case LUA_TTABLE:
	case LUA_TUSERDATA:
	case LUA_TTHREAD:
		// all gc objects will be flushed to disk later
		f.write(&val_(v).gc, sizeof(void*));
		break;
	case LUA_TLCL:
		f.write(&val_(v).gc, sizeof(void*)); // this variant is a gc object
		break;
	case LUA_TLCF: // c-function
		// look up the function in the bindings list
		found = false;
		for(i = 0;i < functions.size();i++)
		{
			if(functions[i] == val_(v).f)
			{
				// write the index as a short
				f.write((ushort)i);
				found = true;
				break;
			}
		}
		if(!found)
			dbgError("unknown light function");
		break;
	default:
		dbgError("unknown object type %i", type);
		break;
	}
}
예제 #4
0
파일: icprecond.C 프로젝트: vivianyw/oofem
void
CompCol_ICPreconditioner :: ICFactor()
{
    int d, g, h, i, j, k, n = pntr_.giveSize() - 1;
    double z;

    for ( k = 0; k < n - 1; k++ ) {
        d = pntr_(k);
        z = val_(d) = sqrt( val_(d) );

        for ( i = d + 1; i < pntr_(k + 1); i++ ) {
            val_(i) /= z;
        }

        for ( i = d + 1; i < pntr_(k + 1); i++ ) {
            z = val_(i);
            h = indx_(i);
            g = i;

            for ( j = pntr_(h); j < pntr_(h + 1); j++ ) {
                for ( ; g < pntr_(k + 1) && indx_(g + 1) <= indx_(j); g++ ) {
                    if ( indx_(g) == indx_(j) ) {
                        val_(j) -= z * val_(g);
                    }
                }
            }
        }
    }

    d = pntr_(n - 1);
    val_(d) = sqrt( val_(d) );
}
예제 #5
0
파일: compcol.C 프로젝트: rreissnerr/oofem
double &CompCol :: operator() (int i, int j)
{
    // increment version
    this->version++;

    for ( int t = colptr_(j); t < colptr_(j + 1); t++ ) {
        if ( rowind_(t) == i ) {
            return val_(t);
        }
    }

    OOFEM_ERROR("Array element (%d,%d) not in sparse structure -- cannot assign", i, j);
    return val_(0); // return to suppress compiler warning message
}
예제 #6
0
파일: compcol.C 프로젝트: rreissnerr/oofem
double &CompCol :: at(int i, int j)
{
    // increment version
    this->version++;

    for ( int t = colptr_(j - 1); t < colptr_(j); t++ ) {
        if ( rowind_(t) == i - 1 ) {
            return val_(t);
        }
    }

    OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j);
    return val_(0); // return to suppress compiler warning message
}
예제 #7
0
void SymCompCol :: zero()
{
    for ( int t = 0; t < nz_; t++ ) {
        val_(t) = 0.0;
    }

    // increment version
    this->version++;
}
예제 #8
0
void SymCompCol :: times(double x)
{
    for ( int t = 0; t < nz_; t++ ) {
        val_(t) *= x;
    }

    // increment version
    this->version++;
}
예제 #9
0
double &SymCompCol :: at(int i, int j)
{
    int ii = i, jj = j;
    if ( ii < jj ) {
        ii = j;
        jj = i;
    }

    // increment version
    this->version++;

    for ( int t = colptr_(jj - 1); t < colptr_(jj); t++ ) {
        if ( rowind_(t) == ( ii - 1 ) ) {
            return val_(t);
        }
    }

    OOFEM_ERROR("SymCompCol::operator(): Array accessing exception -- out of bounds");
    return val_(0); // return to suppress compiler warning message
}
예제 #10
0
template< PSTADE_APPLE_ATL_CSIMPLEARRAY_TEMPLATE_PARAMS, class Value > inline
void pstade_garlic_push_back(
    ATL::CSimpleArray< PSTADE_APPLE_ATL_CSIMPLEARRAY_TEMPLATE_ARGS >& arr,
    Value const& val, pstade::overload<>)
{
#if !defined(PSTADE_APPLE_ATL_HAS_OLD_CSIMPLEARRAY)
    arr.Add(val);
#else
    Value val_(val);
    arr.Add(val_);
#endif
}
예제 #11
0
파일: compcol.C 프로젝트: rreissnerr/oofem
double CompCol :: operator() (int i, int j)  const
{
    for ( int t = colptr_(j); t < colptr_(j + 1); t++ ) {
        if ( rowind_(t) == i ) {
            return val_(t);
        }
    }

    if ( i < dim_ [ 0 ] && j < dim_ [ 1 ] ) {
        return 0.0;
    } else {
        OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j);
        return ( 0 ); // return to suppress compiler warning message
    }
}
예제 #12
0
파일: icprecond.C 프로젝트: vivianyw/oofem
void
CompCol_ICPreconditioner :: initialize(const CompCol &A)
{
    dim_ [ 0 ] = A.dim(0);
    dim_ [ 1 ] = A.dim(1);

    pntr_.resize(A.dim(1) + 1);


    int i, j, k;

    nz_ = 0;
    for ( k = 0; k < dim_ [ 1 ]; k++ ) {
        for ( j = A.col_ptr(k); j < A.col_ptr(k + 1); j++ ) {
            if ( A.row_ind(j) >= k ) {
                nz_++;
            }
        }
    }

    val_.resize(nz_);
    indx_.resize(nz_);

    // Copy just triangular part
    pntr_(0) = 0;
    for ( k = 0; k < dim_ [ 1 ]; k++ ) {
        pntr_(k + 1) = pntr_(k);
        for ( j = A.col_ptr(k); j < A.col_ptr(k + 1); j++ ) {
            if ( A.row_ind(j) >= k ) {
                i = pntr_(k + 1)++;
                val_(i) = A.val(j);
                indx_(i) = A.row_ind(j);
            }
        }
    }

    //  for (i = 0; i < dim_[1]; i++)
    //    qsortRow(indx_, val_, pntr_(i), pntr_(i+1) -1);

    for ( i = 0; i < dim_ [ 1 ]; i++ ) {
        if ( indx_( pntr_(i) ) != i ) {
            OOFEM_ERROR("diagonal not found!");
        }
    }

    this->ICFactor();
}
예제 #13
0
double SymCompCol :: operator() (int i, int j)  const
{
    int ii = i, jj = j;
    if ( ii < jj ) {
        ii = j;
        jj = i;
    }

    for ( int t = colptr_(jj); t < colptr_(jj + 1); t++ ) {
        if ( rowind_(t) == ii ) {
            return val_(t);
        }
    }

    if ( i < dim_ [ 0 ] && j < dim_ [ 1 ] ) {
        return 0.0;
    } else {
        OOFEM_ERROR3("SymCompCol::operator(): Array accessing exception, index out of bounds (%d,%d)", i, j);
        return ( 0 ); // return to suppress compiler warning message
    }
}
예제 #14
0
ICPreconditioner_double::ICPreconditioner_double(const CompRow_Mat_double &A)
  : val_(0), pntr_(A.dim(0)+1), indx_(0), nz_(0)
{
  dim_[0] = A.dim(0);
  dim_[1] = A.dim(1);

  int i, j, k;

  for (k = 0; k < dim_[0]; k++)
    for (j = A.row_ptr(k); j < A.row_ptr(k+1); j++)
      if (A.col_ind(j) >= k)
    nz_++;

  val_.newsize(nz_);
  indx_.newsize(nz_);

  // Copy just triangular part (including diagonal)
  pntr_(0) = 0;
  for (k = 0; k < dim_[0]; k++) {
    pntr_(k+1) = pntr_(k);
    for (j = A.row_ptr(k); j < A.row_ptr(k+1); j++) {
      if (A.col_ind(j) >= k) {
    i = pntr_(k+1)++;
    val_(i) = A.val(j);
    indx_(i) = A.col_ind(j);
      }
    }
  }

  for (i = 0; i < dim_[0]; i++)
    QSort(indx_, val_, pntr_[i], pntr_[i+1] - pntr_[i]);

  for (i = 0; i < dim_[0]; i++)
    if (indx_[pntr_(i)] != i) {
      std::cerr << "IC Preconditioner: diagonal not found!" << i << "\n";
      exit(1);
    }
  
  ICFactor(pntr_, indx_, val_);
}
예제 #15
0
파일: compcol.C 프로젝트: rreissnerr/oofem
void CompCol :: times(const FloatArray &x, FloatArray &answer) const
{
    int M = dim_ [ 0 ];
    int N = dim_ [ 1 ];

    //      Check for compatible dimensions:
    if ( x.giveSize() != N ) {
        OOFEM_ERROR("incompatible dimensions");
    }

    answer.resize(M);
    answer.zero();

    int j, t;
    double rhs;

    for ( j = 0; j < N; j++ ) {
        rhs = x(j);
        for ( t = colptr_(j); t < colptr_(j + 1); t++ ) {
            answer( rowind_(t) ) += val_(t) * rhs;
        }
    }
}
예제 #16
0
파일: compcol.C 프로젝트: rreissnerr/oofem
void CompCol :: timesT(const FloatArray &x, FloatArray &answer) const
{
    int M = dim_ [ 0 ];
    int N = dim_ [ 1 ];

    //      Check for compatible dimensions:
    if ( x.giveSize() != M ) {
        OOFEM_ERROR("Error in CompCol -- incompatible dimensions");
    }

    answer.resize(N);
    answer.zero();
    int i, t;
    double r;

    for ( i = 0; i < N; i++ ) {
        r = 0.0;
        for ( t = colptr_(i); t < colptr_(i + 1); t++ ) {
            r += val_(t) * x( rowind_(t) );
        }

        answer(i) = r;
    }
}