コード例 #1
0
void TrilinearElementTypeSuite_TestShape( TrilinearElementTypeSuiteData* data ) {
   FeMesh*   mesh = NULL;
   int       nEls, nVerts, nDims;
   const int *verts;
   double*   vert = NULL;
   double    lCrd[3] = { 0.0, 0.0, 0.0 };
   double    basis[8] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
   IArray*   inc;
   int       e_i, v_i, v_j;

   mesh = buildMesh();
   pcu_check_true( mesh );
   Stg_Component_Initialise( mesh, data, True );

   nDims = Mesh_GetDimSize( mesh );
   nEls = Mesh_GetDomainSize( mesh, nDims );
   inc = IArray_New();

   for( e_i = 0; e_i < nEls; e_i++ ) {
      Mesh_GetIncidence( mesh, nDims, e_i, 0, inc );
      nVerts = IArray_GetSize( inc );
      verts = IArray_GetPtr( inc );

      for( v_i = 0; v_i < nVerts; v_i++ ) {
         vert = Mesh_GetVertex( mesh, verts[v_i] );
         FeMesh_CoordGlobalToLocal( mesh, e_i, vert, lCrd );
         FeMesh_EvalBasis( mesh, e_i, lCrd, basis );

         for( v_j = 0; v_j < nVerts; v_j++ ) {
            if( (v_i == v_j && !Num_Approx( basis[v_j], 1.0 )) || (v_i != v_j && !Num_Approx( basis[v_j], 0.0 )) ) {
               break;
            }
         }
         if( v_j < nVerts )
            break;
      }
      if( v_i < nVerts )
         break;
   }
   pcu_check_true( e_i == nEls );

   Stg_Class_Delete( inc );

   _Stg_Component_Delete( mesh );
}
コード例 #2
0
Fn::GradFeVariableFn::func Fn::GradFeVariableFn::getFunction( IOsptr sample_input )
{

    // setup output
    FeVariable* fevar = (FeVariable*)_fevariable;
    int numComponents = fevar->fieldComponentCount;

    FunctionIO::IOType iotype;
    std::shared_ptr<IO_double> _output;
    if (fevar->dim == 1) {
        iotype = FunctionIO::Vector;
    } else
        iotype = FunctionIO::Tensor;
    
    _output = std::make_shared<IO_double>(numComponents*fevar->dim, iotype);

    // if input is FEMCoordinate, eject appropriate lambda
    std::shared_ptr<const FEMCoordinate> femCoord = std::dynamic_pointer_cast<const FEMCoordinate>(sample_input);
    if ( femCoord ){
        if( femCoord->mesh() == (void*) (fevar->feMesh->parentMesh ) )
            return [_output,fevar](IOsptr input)->IOsptr {
                std::shared_ptr<const FEMCoordinate> femCoord = debug_dynamic_cast<const FEMCoordinate>(input);
                
                FeVariable_InterpolateDerivativesToElLocalCoord( fevar, femCoord->index(), femCoord->localCoord()->data(), _output->data() );

                return debug_dynamic_cast<const FunctionIO>(_output);
            };
    };

    // if input is MeshCoordinate, eject appropriate lambda
    std::shared_ptr<const MeshCoordinate> meshCoord = std::dynamic_pointer_cast<const MeshCoordinate>(sample_input);
    if ( meshCoord ){
        if( meshCoord->object() == (void*) (fevar->feMesh) )  // in this case, we need the identical mesh
        {
            std::shared_ptr<IArrayClass> inc = std::make_shared<IArrayClass>();
            return [_output,fevar,inc](IOsptr input)->IOsptr {
                std::shared_ptr<const MeshCoordinate> meshCoord = debug_dynamic_cast<const MeshCoordinate>(input);
                unsigned index = meshCoord->index();
                // from OperatorFeVariable.c
                /* Find the elements around the node and point to them via the nbrElList. */
                FeMesh_GetNodeElements( (void*)fevar->feMesh, index, (IArray*)inc->inc );
                unsigned nbrElCount = IArray_GetSize( inc->inc );
                int*     nbrElList  = IArray_GetPtr( inc->inc );
                Coord  elLocalCoord;

                /* Use last element in list, get local coords then interpolate value. */
                FeMesh_CoordGlobalToLocal( fevar->feMesh, nbrElList[nbrElCount-1], Mesh_GetVertex( fevar->feMesh, index ), elLocalCoord );

                /* Get value at node for this element. */
                FeVariable_InterpolateDerivativesToElLocalCoord( fevar, nbrElList[nbrElCount-1], elLocalCoord, _output->data() );

                return debug_dynamic_cast<const FunctionIO>(_output);
            };
        }
    }
    
    // if neither of the above worked, try plain old global coord
    std::shared_ptr<const IO_double> iodouble = std::dynamic_pointer_cast<const IO_double>(sample_input);
    if ( iodouble ){
        return [_output,fevar](IOsptr input)->IOsptr {
            std::shared_ptr<const IO_double> iodouble = debug_dynamic_cast<const IO_double>(input);            

            InterpolationResult retval = FeVariable_InterpolateDerivativesAt( (void*)fevar, (double*)iodouble->data(), (double*) _output->data() );
            
            if (! ( (retval == LOCAL) || (retval == SHADOW) ) ){
                std::stringstream streamguy;
                streamguy << "FeVariable derivative interpolation at location (" << iodouble->at(0);
                for (unsigned ii=1; ii<iodouble->size(); ii++)
                    streamguy << ", "<< iodouble->at(ii);
                streamguy << ") does not appear to be valid.\nLocation is probably outside local domain.";
                
                throw std::runtime_error(streamguy.str());
            }


            return debug_dynamic_cast<const FunctionIO>(_output);
        };
    }
    
    // if we get here, something aint right
    throw std::invalid_argument("'GradFeVariableFn' does not appear to be compatible with provided input type.");

    
}