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++; } }
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; }