int DofManValueField :: evaluateAt(FloatArray &answer, const FloatArray &coords, ValueModeType mode, TimeStep *tStep) { int result = 0; // assume ok FloatArray lc, n; // request element containing target point Element *elem = this->domain->giveSpatialLocalizer()->giveElementContainingPoint(coords); if ( elem ) { // ok element containing target point found FEInterpolation *interp = elem->giveInterpolation(); if ( interp ) { // map target point to element local coordinates if ( interp->global2local( lc, coords, FEIElementGeometryWrapper(elem) ) ) { // evaluate interpolation functions at target point interp->evalN( n, lc, FEIElementGeometryWrapper(elem) ); // loop over element nodes for ( int i = 1; i <= n.giveSize(); i++ ) { // multiply nodal value by value of corresponding shape function and add this to answer answer.add( n.at(i), this->dmanvallist[elem->giveDofManagerNumber(i)-1] ); } } else { // mapping from global to local coordinates failed result = 1; // failed } } else { // element without interpolation result = 1; // failed } } else { // no element containing given point found result = 1; // failed } return result; }
int SmoothedNodalInternalVariableField :: evaluateAt(FloatArray &answer, FloatArray &coords, ValueModeType mode, TimeStep *tStep) { int result = 0; // assume ok FloatArray lc, n; const FloatArray *nodalValue; // use whole domain recovery // create a new set containing all elements Set elemSet(0, this->domain); elemSet.addAllElements(); this->smoother->recoverValues(elemSet, istType, tStep); // request element containing target point Element *elem = this->domain->giveSpatialLocalizer()->giveElementContainingPoint(coords); if ( elem ) { // ok element containing target point found FEInterpolation *interp = elem->giveInterpolation(); if ( interp ) { // map target point to element local coordinates if ( interp->global2local( lc, coords, FEIElementGeometryWrapper(elem) ) ) { // evaluate interpolation functions at target point interp->evalN( n, lc, FEIElementGeometryWrapper(elem) ); // loop over element nodes for ( int i = 1; i <= n.giveSize(); i++ ) { // request nodal value this->smoother->giveNodalVector( nodalValue, elem->giveDofManagerNumber(i) ); // multiply nodal value by value of corresponding shape function and add this to answer answer.add(n.at(i), * nodalValue); } } else { // mapping from global to local coordinates failed result = 1; // failed } } else { // element without interpolation result = 1; // failed } } else { // no element containing given point found result = 1; // failed } return result; }
void HangingNode :: postInitialize() { Node :: postInitialize(); Element *e; FEInterpolation *fei; FloatArray lcoords, masterContribution; #ifdef __OOFEG if ( initialized ) { return; } initialized = true; #endif // First check element and interpolation if ( masterElement == -1 ) { // Then we find it by taking the closest (probably containing element) FloatArray closest; SpatialLocalizer *sp = this->domain->giveSpatialLocalizer(); sp->init(); // Closest point or containing point? It should be contained, but with numerical errors it might be slightly outside // so the closest point is more robust. if ( !( e = sp->giveElementClosestToPoint(lcoords, closest, coordinates, this->masterRegion) ) ) { OOFEM_ERROR("Couldn't find closest element (automatically)."); } this->masterElement = e->giveNumber(); } else if ( !( e = this->giveDomain()->giveElement(this->masterElement) ) ) { OOFEM_ERROR("Requested element %d doesn't exist.", this->masterElement); } if ( !( fei = e->giveInterpolation() ) ) { OOFEM_ERROR("Requested element %d doesn't have a interpolator.", this->masterElement); } if ( lcoords.giveSize() == 0 ) { // we don't need to do this again if the spatial localizer was used. fei->global2local( lcoords, coordinates, FEIElementGeometryWrapper(e) ); } // Initialize slave dofs (inside check of consistency of receiver and master dof) const IntArray &masterNodes = e->giveDofManArray(); for ( Dof *dof: *this ) { SlaveDof *sdof = dynamic_cast< SlaveDof * >(dof); if ( sdof ) { DofIDItem id = sdof->giveDofID(); fei = e->giveInterpolation(id); if ( !fei ) { OOFEM_ERROR("Requested interpolation for dof id %d doesn't exist in element %d.", id, this->masterElement); } #if 0 // This won't work (yet), as it requires some more general FEI classes, or something similar. if ( fei->hasMultiField() ) { FloatMatrix multiContribution; IntArray masterDofIDs, masterNodesDup, dofids; fei->evalMultiN(multiContribution, dofids, lcoords, FEIElementGeometryWrapper(e), 0.0); masterContribution.flatten(multiContribution); masterDofIDs.clear(); for ( int i = 0; i <= multiContribution.giveNumberOfColumns(); ++i ) { masterDofIDs.followedBy(dofids); masterNodesDup.followedBy(masterNodes); } sdof->initialize(masterNodesDup, & masterDofIDs, masterContribution); } else { } #else // Note: There can be more masterNodes than masterContributions, since all the // FEI classes are based on that the first nodes correspond to the simpler/linear interpolation. // If this assumption is changed in FEIElementGeometryWrapper + friends, // masterNode will also need to be modified for each dof accordingly. fei->evalN( masterContribution, lcoords, FEIElementGeometryWrapper(e) ); sdof->initialize(masterNodes, IntArray(), masterContribution); #endif } } }