LCOV - code coverage report
Current view: top level - src/LocalDiscretization - ElemEvaluator.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 50 66 75.8 %
Date: 2020-12-16 07:07:30 Functions: 6 6 100.0 %
Branches: 71 128 55.5 %

           Branch data     Line data    Source code
       1                 :            : #include <limits>
       2                 :            : 
       3                 :            : #include "moab/ElemEvaluator.hpp"
       4                 :            : #include "moab/CartVect.hpp"
       5                 :            : #include "moab/Matrix3.hpp"
       6                 :            : 
       7                 :            : // need to include eval set types here to support get_eval_set; alternative would be to have some
       8                 :            : // type of registration, but we'd still need static registration for the built-in types
       9                 :            : #include "moab/LocalDiscretization/LinearTri.hpp"
      10                 :            : #include "moab/LocalDiscretization/LinearQuad.hpp"
      11                 :            : #include "moab/LocalDiscretization/LinearTet.hpp"
      12                 :            : #include "moab/LocalDiscretization/LinearHex.hpp"
      13                 :            : #include "moab/LocalDiscretization/QuadraticHex.hpp"
      14                 :            : //#include "moab/SpectralQuad.hpp"
      15                 :            : //#include "moab/SpectralHex.hpp"
      16                 :            : 
      17                 :            : namespace moab
      18                 :            : {
      19                 :      10910 : ErrorCode EvalSet::evaluate_reverse( EvalFcn eval, JacobianFcn jacob, InsideFcn inside_f, const double* posn,
      20                 :            :                                      const double* verts, const int nverts, const int ndim, const double iter_tol,
      21                 :            :                                      const double inside_tol, double* work, double* params, int* inside )
      22                 :            : {
      23                 :            :     // TODO: should differentiate between epsilons used for
      24                 :            :     // Newton Raphson iteration, and epsilons used for curved boundary geometry errors
      25                 :            :     // right now, fix the tolerance used for NR
      26                 :      10910 :     const double error_tol_sqr = iter_tol * iter_tol;
      27                 :      10910 :     CartVect* cvparams         = reinterpret_cast< CartVect* >( params );
      28                 :      10910 :     const CartVect* cvposn     = reinterpret_cast< const CartVect* >( posn );
      29                 :            : 
      30                 :            :     // initialize to center of element
      31         [ +  - ]:      10910 :     *cvparams = CartVect( -.4 );
      32                 :            : 
      33         [ +  - ]:      10910 :     CartVect new_pos;
      34                 :            :     // evaluate that first guess to get a new position
      35         [ +  - ]:      10910 :     ErrorCode rval = ( *eval )( cvparams->array(), verts, ndim,
      36                 :            :                                 3,  // hardwire to num_tuples to 3 since the field is coords
      37 [ +  - ][ +  - ]:      21820 :                                 work, new_pos.array() );
      38         [ -  + ]:      10910 :     if( MB_SUCCESS != rval ) return rval;
      39                 :            : 
      40                 :            :     // residual is diff between old and new pos; need to minimize that
      41         [ +  - ]:      10910 :     CartVect res = new_pos - *cvposn;
      42         [ +  - ]:      10910 :     Matrix3 J;
      43         [ -  + ]:      10910 :     int dum, *tmp_inside = ( inside ? inside : &dum );
      44                 :            : 
      45                 :      10910 :     int iters = 0;
      46                 :            :     // while |res| larger than tol
      47 [ +  - ][ +  + ]:      21807 :     while( res % res > error_tol_sqr )
      48                 :            :     {
      49         [ -  + ]:      10897 :         if( ++iters > 10 )
      50                 :            :         {
      51                 :            :             // if we haven't converged but we're outside, that's defined as success
      52         [ #  # ]:          0 :             *tmp_inside = ( *inside_f )( params, ndim, inside_tol );
      53         [ #  # ]:          0 :             if( !( *tmp_inside ) )
      54                 :          0 :                 return MB_SUCCESS;
      55                 :            :             else
      56                 :          0 :                 return MB_FAILURE;
      57                 :            :         }
      58                 :            : 
      59                 :            :         // get jacobian at current params
      60 [ +  - ][ +  - ]:      10897 :         rval       = ( *jacob )( cvparams->array(), verts, nverts, ndim, work, J.array() );
                 [ +  - ]
      61         [ +  - ]:      10897 :         double det = J.determinant();
      62         [ -  + ]:      10897 :         if( det < std::numeric_limits< double >::epsilon() )
      63                 :            :         {
      64         [ #  # ]:          0 :             *tmp_inside = ( *inside_f )( params, ndim, inside_tol );
      65         [ #  # ]:          0 :             if( !( *tmp_inside ) )
      66                 :          0 :                 return MB_SUCCESS;
      67                 :            :             else
      68                 :          0 :                 return MB_INDEX_OUT_OF_RANGE;
      69                 :            :         }
      70                 :            : 
      71                 :            :         // new params tries to eliminate residual
      72 [ +  - ][ +  - ]:      10897 :         *cvparams -= J.inverse() * res;
                 [ +  - ]
      73                 :            : 
      74                 :            :         // get the new forward-evaluated position, and its difference from the target pt
      75                 :            :         rval = ( *eval )( params, verts, ndim,
      76                 :            :                           3,  // hardwire to num_tuples to 3 since the field is coords
      77 [ +  - ][ +  - ]:      10897 :                           work, new_pos.array() );
      78         [ -  + ]:      10897 :         if( MB_SUCCESS != rval ) return rval;
      79         [ +  - ]:      10897 :         res = new_pos - *cvposn;
      80                 :            :     }
      81                 :            : 
      82 [ +  - ][ +  - ]:      10910 :     if( inside ) *inside = ( *inside_f )( params, ndim, inside_tol );
      83                 :            : 
      84                 :      10910 :     return MB_SUCCESS;
      85                 :            : }  // Map::evaluate_reverse()
      86                 :            : 
      87                 :      14903 : int EvalSet::inside_function( const double* params, const int ndims, const double tol )
      88                 :            : {
      89 [ +  + ][ +  + ]:      14903 :     if( params[0] >= -1 - tol && params[0] <= 1 + tol &&
                 [ +  - ]
      90 [ +  + ][ +  + ]:      12966 :         ( ndims < 2 || ( params[1] >= -1 - tol && params[1] <= 1 + tol ) ) &&
                 [ +  + ]
      91 [ +  + ][ +  + ]:       8066 :         ( ndims < 3 || ( params[2] >= -1 - tol && params[2] <= 1 + tol ) ) )
      92                 :       9986 :         return true;
      93                 :            :     else
      94                 :       4917 :         return false;
      95                 :            : }
      96                 :            : 
      97                 :            : /** \brief Given type & #vertices, get an appropriate eval set */
      98                 :          9 : ErrorCode EvalSet::get_eval_set( EntityType tp, unsigned int num_vertices, EvalSet& eval_set )
      99                 :            : {
     100   [ -  +  +  -  :          9 :     switch( tp )
                   +  - ]
     101                 :            :     {
     102                 :            :         case MBEDGE:
     103                 :          0 :             break;
     104                 :            :         case MBTRI:
     105         [ +  - ]:          2 :             if( LinearTri::compatible( tp, num_vertices, eval_set ) ) return MB_SUCCESS;
     106                 :          0 :             break;
     107                 :            :         case MBQUAD:
     108         [ +  - ]:          2 :             if( LinearQuad::compatible( tp, num_vertices, eval_set ) ) return MB_SUCCESS;
     109                 :            :             //            if (SpectralQuad::compatible(tp, num_vertices, eval_set)) return
     110                 :            :             //            MB_SUCCESS;
     111                 :          0 :             break;
     112                 :            :         case MBTET:
     113         [ #  # ]:          0 :             if( LinearTet::compatible( tp, num_vertices, eval_set ) ) return MB_SUCCESS;
     114                 :          0 :             break;
     115                 :            :         case MBHEX:
     116         [ +  + ]:          5 :             if( LinearHex::compatible( tp, num_vertices, eval_set ) ) return MB_SUCCESS;
     117         [ +  - ]:          1 :             if( QuadraticHex::compatible( tp, num_vertices, eval_set ) ) return MB_SUCCESS;
     118                 :            :             //            if (SpectralHex::compatible(tp, num_vertices, eval_set)) return
     119                 :            :             //            MB_SUCCESS;
     120                 :          0 :             break;
     121                 :            :         default:
     122                 :          0 :             break;
     123                 :            :     }
     124                 :            : 
     125                 :          0 :     return MB_NOT_IMPLEMENTED;
     126                 :            : }
     127                 :            : 
     128                 :       2142 : ErrorCode ElemEvaluator::find_containing_entity( Range& entities, const double* point, const double iter_tol,
     129                 :            :                                                  const double inside_tol, EntityHandle& containing_ent, double* params,
     130                 :            :                                                  unsigned int* num_evals )
     131                 :            : {
     132                 :            :     int is_inside;
     133                 :       2142 :     ErrorCode rval      = MB_SUCCESS;
     134                 :       2142 :     unsigned int nevals = 0;
     135         [ +  - ]:       2142 :     Range::iterator i;
     136 [ +  - ][ +  - ]:       7059 :     for( i = entities.begin(); i != entities.end(); ++i )
         [ +  - ][ +  - ]
                 [ +  + ]
     137                 :            :     {
     138                 :       6917 :         nevals++;
     139 [ +  - ][ +  - ]:       6917 :         set_ent_handle( *i );
     140         [ +  - ]:       6917 :         rval = reverse_eval( point, iter_tol, inside_tol, params, &is_inside );
     141         [ -  + ]:       6917 :         if( MB_SUCCESS != rval ) return rval;
     142         [ +  + ]:       6917 :         if( is_inside ) break;
     143                 :            :     }
     144 [ +  - ][ +  - ]:       2142 :     containing_ent = ( i == entities.end() ? 0 : *i );
         [ +  + ][ +  - ]
     145         [ +  - ]:       2142 :     if( num_evals ) *num_evals += nevals;
     146                 :       2142 :     return MB_SUCCESS;
     147                 :            : }
     148 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11