void PrescribedGradientBCNeumann :: giveLocationArrays(std :: vector< IntArray > &rows, std :: vector< IntArray > &cols, CharType type,
                                                       const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s)
{
    IntArray bNodes, dofids;
    IntArray loc_r, loc_c, sigma_loc_r, sigma_loc_c;
    int nsd = this->domain->giveNumberOfSpatialDimensions();
    DofIDItem id0 = this->domain->giveDofManager(1)->hasDofID(V_u) ? V_u : D_u; // Just check the first node if it has V_u or D_u.
    dofids.resize(nsd);
    for ( int i = 0; i < nsd; ++i ) {
        dofids(i) = id0 + i;
    }

    // Fetch the columns/rows for the stress contributions;
    mpSigmaHom->giveCompleteLocationArray(sigma_loc_r, r_s);
    mpSigmaHom->giveCompleteLocationArray(sigma_loc_c, c_s);

    Set *set = this->giveDomain()->giveSet(this->set);
    const IntArray &boundaries = set->giveBoundaryList();

    rows.resize( boundaries.giveSize() );
    cols.resize( boundaries.giveSize() );
    int i = 0;
    for ( int pos = 1; pos <= boundaries.giveSize() / 2; ++pos ) {
        Element *e = this->giveDomain()->giveElement( boundaries.at(pos * 2 - 1) );

        // Here, we could use only the nodes actually located on the boundary, but we don't.
        // Instead, we use all nodes belonging to the element, which is allowed because the
        // basis functions related to the interior nodes will be zero on the boundary.
        // Obviously, this is less efficient, so why do we want to do it this way?
        // Because it is easier when XFEM enrichments are present. /ES
        e->giveLocationArray(loc_r, r_s);
        e->giveLocationArray(loc_c, c_s);

        // For most uses, loc_r == loc_c, and sigma_loc_r == sigma_loc_c.
        rows [ i ] = loc_r;
        cols [ i ] = sigma_loc_c;
        i++;
        // and the symmetric part (usually the transpose of above)
        rows [ i ] = sigma_loc_r;
        cols [ i ] = loc_c;
        i++;
    }
}
Esempio n. 2
0
contextIOResultType DofManager :: restoreContext(DataStream &stream, ContextMode mode, void *obj)
//
// restores full node context (saves state variables, that completely describe
// current state)
//
{
    contextIOResultType iores;

    if ( ( iores = FEMComponent :: restoreContext(stream, mode, obj) ) != CIO_OK ) {
        THROW_CIOERR(iores);
    }

    int _numberOfDofs;
    if ( !stream.read(_numberOfDofs) ) {
        THROW_CIOERR(CIO_IOERR);
    }

    IntArray dtypes(_numberOfDofs);
    // restore dof types
    for ( int i = 1; i <= _numberOfDofs; i++ ) {
        if ( !stream.read(dtypes.at(i)) ) {
            THROW_CIOERR(CIO_IOERR);
        }
    }
    
    IntArray dofids(_numberOfDofs);
    // restore dof ids
    for ( int i = 1; i <= _numberOfDofs; i++ ) {
        if ( !stream.read(dofids.at(i)) ) {
            THROW_CIOERR(CIO_IOERR);
        }
    }

    // allocate new ones
    for ( auto &d: dofArray) { delete d; } ///@todo Smart pointers would be nicer here
    dofArray.clear();
    for ( int i = 0; i < _numberOfDofs; i++ ) {
        Dof *dof = classFactory.createDof( ( dofType ) dtypes(i), (DofIDItem)dofids(i), this );
        this->appendDof(dof);
    }

    if ( mode & CM_Definition ) {
        if ( ( iores = loadArray.restoreYourself(stream) ) != CIO_OK ) {
            THROW_CIOERR(iores);
        }

        if ( !stream.read(isBoundaryFlag) ) {
            THROW_CIOERR(CIO_IOERR);
        }

        if ( !stream.read(hasSlaveDofs) ) {
            THROW_CIOERR(CIO_IOERR);
        }

        if ( !stream.read(globalNumber) ) {
            THROW_CIOERR(CIO_IOERR);
        }

        int _val;
        if ( !stream.read(_val) ) {
            THROW_CIOERR(CIO_IOERR);
        }

        parallel_mode = ( dofManagerParallelMode ) _val;
        if ( ( iores = partitions.restoreYourself(stream) ) != CIO_OK ) {
            THROW_CIOERR(iores);
        }
    }

    for ( Dof *dof: *this ) {
        if ( ( iores = dof->restoreContext(stream, mode, obj) ) != CIO_OK ) {
            THROW_CIOERR(iores);
        }
    }

    return CIO_OK;
}