コード例 #1
0
ファイル: ElementType.cpp プロジェクト: andrealani/coolfluid3
RealVector ElementType::plane_jacobian_normal(const RealVector& mapped_coords,
                                              const RealMatrix& nodes,
                                              const CoordRef direction) const
{
  throw Common::NotImplemented(FromHere(),"jacobian not implemented for "+derived_type_name());
  return RealVector(1);
}
コード例 #2
0
ファイル: LPSolver.cpp プロジェクト: soberg/fruitcase
   /* bool LPSolver::Simplex(int phase) {
        int x = phase == 1 ? m+1 : m;
        while (true) {
            int s = -1;
            for (int j = 0; j <= n; j++) {
                if (phase == 2 && N[j] == -1) continue;
                if (s == -1 || D[x][j] < D[x][s] || D[x][j] == D[x][s] && N[j] < N[s]) s = j;
            }
            if (D[x][s] >= -EPS) return true; // fertig
            int r = -1;
            for (int i = 0; i < m; i++) {
                if (D[i][s] <= 0) continue;
                if (r == -1 || D[i][n+1] / D[i][s] < D[r][n+1] / D[r][s] ||
                    D[i][n+1] / D[i][s] == D[r][n+1] / D[r][s] && B[i] < B[r]) r = i;
            }
            if (r == -1) return false; // alle eintraege in der spalte negativ -> unbeschraenkt!
            Pivot(r, s);
        }
    }*/
double LPSolver::Solve(RealVector &x)
{
    int r = 0;
    for (int i = 1; i < m; i++) if (D(i,n+1) < D(r,n+1)) r = i;
    // D[r][n+1] smalles element
    
    // if < 0
    
    // phase 1
    if (D(r,n+1) <= -eps) {
        Pivot(r, n);
        if (!Simplex(1) || D(m+1,n+1) < -eps) return -std::numeric_limits<double>::infinity();  // infeasible!
        for (int i = 0; i < m; i++)
            if (B[i] == -1)
            {
                int s = -1;
                for (int j = 0; j <= n; j++)
                    if (s == -1 || D(i,j) < D(i,s) || D(i,j) == D(i,s) && N[j] < N[s]) s = j;
                Pivot(i, s);
            }
    }
    // otherwise phase 2...
    if (!Simplex(2)) return std::numeric_limits<double>::infinity();    // unbounded
    x = RealVector(n);
    for (int i = 0; i < m; i++) if (B[i] < n) x(B[i]) = D(i,n+1);
    return D(m,n+1);
}
コード例 #3
0
void RelaxedVarConstraints::build_active_views()
{
  const SizetArray& vc_totals = sharedVarsData.components_totals();
  size_t num_mdv  = vc_totals[0] + vc_totals[1]  + vc_totals[2],
         num_mauv = vc_totals[3] + vc_totals[4]  + vc_totals[5],
         num_meuv = vc_totals[6] + vc_totals[7]  + vc_totals[8],
         num_muv  = num_mauv + num_meuv,
         num_msv  = vc_totals[9] + vc_totals[10] + vc_totals[11];

  // Initialize active views
  size_t cv_start, num_cv;
  switch (sharedVarsData.view().first) {
  case EMPTY:
    Cerr << "Error: active view cannot be EMPTY in RelaxedVarConstraints."
	 << std::endl;
    abort_handler(-1);
    break;
  case RELAXED_ALL:
    cv_start = 0;                 num_cv = num_mdv + num_muv + num_msv; break;
  case RELAXED_DESIGN:
    cv_start = 0;                 num_cv = num_mdv;                     break;
  case RELAXED_ALEATORY_UNCERTAIN:
    cv_start = num_mdv;           num_cv = num_mauv;                    break;
  case RELAXED_EPISTEMIC_UNCERTAIN:
    cv_start = num_mdv+num_mauv;  num_cv = num_meuv;                    break;
  case RELAXED_UNCERTAIN:
    cv_start = num_mdv;           num_cv = num_muv;                     break;
  case RELAXED_STATE:
    cv_start = num_mdv + num_muv; num_cv = num_msv;                     break;
  }
  if (num_cv) {
    continuousLowerBnds = RealVector(Teuchos::View,
      &allContinuousLowerBnds[cv_start], num_cv);
    continuousUpperBnds = RealVector(Teuchos::View,
      &allContinuousUpperBnds[cv_start], num_cv);
  }
}
コード例 #4
0
void RelaxedVariables::build_active_views()
{
  // Initialize active view vectors and counts.  Don't bleed over any logic
  // about supported view combinations; rather, keep this class general and
  // encapsulated.
  const SizetArray& vc_totals = sharedVarsData.components_totals();
  size_t num_cdv = vc_totals[0], num_ddv = vc_totals[1] + vc_totals[2],
    num_mdv  = num_cdv + num_ddv, num_cauv = vc_totals[3],
    num_dauv = vc_totals[4] + vc_totals[5], num_ceuv = vc_totals[6],
    num_deuv = vc_totals[7] + vc_totals[8], num_mauv = num_cauv + num_dauv,
    num_meuv = num_ceuv + num_deuv, num_muv = num_mauv + num_meuv,
    num_csv  = vc_totals[9], num_dsv = vc_totals[10] + vc_totals[11],
    num_msv  = num_csv + num_dsv;

  // Initialize active views
  size_t cv_start, num_cv;
  switch (sharedVarsData.view().first) {
  case EMPTY:
    Cerr << "Error: active view cannot be EMPTY in RelaxedVariables."
	 << std::endl; abort_handler(-1);             break;
  case RELAXED_ALL:
    // start at the beginning
    cv_start = 0; num_cv = num_mdv + num_muv + num_msv; break;
  case RELAXED_DESIGN:
    // start at the beginning
    cv_start = 0; num_cv = num_mdv;                     break;
  case RELAXED_ALEATORY_UNCERTAIN:
    // skip over the relaxed design variables
    cv_start = num_mdv; num_cv = num_mauv;              break;
  case RELAXED_EPISTEMIC_UNCERTAIN:
    // skip over the relaxed design and aleatory variables
    cv_start = num_mdv+num_mauv;  num_cv = num_meuv;    break;
  case RELAXED_UNCERTAIN:
    // skip over the relaxed design variables
    cv_start = num_mdv; num_cv = num_muv;               break;
  case RELAXED_STATE:
    // skip over the relaxed design and uncertain variables
    cv_start = num_mdv + num_muv; num_cv = num_msv;     break;
  }
  sharedVarsData.cv_start(cv_start); sharedVarsData.cv(num_cv);
  sharedVarsData.div_start(0);       sharedVarsData.div(0);
  sharedVarsData.drv_start(0);       sharedVarsData.drv(0);
  sharedVarsData.initialize_active_components();
  if (num_cv)
    continuousVars
      = RealVector(Teuchos::View, &allContinuousVars[cv_start], num_cv);
}
コード例 #5
0
void MixedVariables::build_inactive_views()
{
  // Initialize continuousVarTypes/discreteVarTypes/continuousVarIds.
  // Don't bleed over any logic about supported view combinations; rather,
  // keep this class general and encapsulated.
  const SizetArray& vc_totals = sharedVarsData.components_totals();
  size_t num_cdv = vc_totals[0], num_ddiv = vc_totals[1],
    num_ddrv  = vc_totals[2], num_cauv = vc_totals[3], num_dauiv = vc_totals[4],
    num_daurv = vc_totals[5], num_ceuv = vc_totals[6], num_deuiv = vc_totals[7],
    num_deurv = vc_totals[8], num_csv  = vc_totals[9], num_dsiv = vc_totals[10],
    num_dsrv  = vc_totals[11];

  // Initialize inactive views
  size_t icv_start, idiv_start, idrv_start, num_icv, num_idiv, num_idrv;
  switch (sharedVarsData.view().second) {
  case EMPTY:
    icv_start = idiv_start = idrv_start = num_icv = num_idiv = num_idrv = 0;
    break;
  case MIXED_ALL:
    Cerr << "Error: inactive view cannot be MIXED_ALL in MixedVariables."
	 << std::endl;
    abort_handler(-1);                                                 break;
  case MIXED_DESIGN:
    // start at the beginning
    icv_start = idiv_start = idrv_start = 0;
    num_icv  = num_cdv;
    num_idiv = num_ddiv;
    num_idrv = num_ddrv;                                                break;
  case MIXED_ALEATORY_UNCERTAIN:
    // skip over the design variables
    icv_start  = num_cdv;  num_icv  = num_cauv;
    idiv_start = num_ddiv; num_idiv = num_dauiv;
    idrv_start = num_ddrv; num_idrv = num_daurv;                         break;
  case MIXED_EPISTEMIC_UNCERTAIN:
    // skip over the design and aleatory uncertain variables
    icv_start  = num_cdv  + num_cauv;  num_icv  = num_ceuv;
    idiv_start = num_ddiv + num_dauiv; num_idiv = num_deuiv;
    idrv_start = num_ddrv + num_daurv; num_idrv = num_deurv;             break;
  case MIXED_UNCERTAIN:
    // skip over the design variables
    icv_start  = num_cdv;  num_icv  = num_cauv  + num_ceuv;
    idiv_start = num_ddiv; num_idiv = num_dauiv + num_deuiv;
    idrv_start = num_ddrv; num_idrv = num_daurv + num_deurv;             break;
  case MIXED_STATE:
    // skip over all the design and uncertain variables
    icv_start  = num_cdv  + num_cauv  + num_ceuv;  num_icv  = num_csv;
    idiv_start = num_ddiv + num_dauiv + num_deuiv; num_idiv = num_dsiv;
    idrv_start = num_ddrv + num_daurv + num_deurv; num_idrv = num_dsrv;  break;
  }
  sharedVarsData.icv_start(icv_start);   sharedVarsData.icv(num_icv);
  sharedVarsData.idiv_start(idiv_start); sharedVarsData.idiv(num_idiv);
  sharedVarsData.idrv_start(idrv_start); sharedVarsData.idrv(num_idrv);
  sharedVarsData.initialize_inactive_components();
  if (num_icv)
    inactiveContinuousVars
      = RealVector(Teuchos::View, &allContinuousVars[icv_start],    num_icv);
  if (num_idiv)
    inactiveDiscreteIntVars
      = IntVector(Teuchos::View,  &allDiscreteIntVars[idiv_start],  num_idiv);
  if (num_idrv)
    inactiveDiscreteRealVars
      = RealVector(Teuchos::View, &allDiscreteRealVars[idrv_start], num_idrv);
}
コード例 #6
0
ファイル: layer.cpp プロジェクト: bin3/toyml
bool Layer::Init(const Options& options) {
  options_ = options;
  RealMatrix(options_.out, options_.in, 0).swap(w_);
  RealVector(options_.out, 0).swap(b_);
  return true;
}
コード例 #7
0
ファイル: DevSuite.cpp プロジェクト: marcelra/plingtheory
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// devImprovedPeakAlgorithm
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void DevSuite::devImprovedPeakAlgorithm()
{
   Logger msg( "devImprovedPeakAlgorithm" );
   msg << Msg::Info << "Running devImprovedPeakAlgorithm..." << Msg::EndReq;

   // Take fourier bin size = 4096
   // Take sine with phase = 0
   // Make center frequency variable
   // Pick range around center frequency with delta_freq
   // Compute max rel amp as function of freq delta (envelope)
   // First sort by amp, remove all non-increasing frequency entries

   size_t fourierSize = 4096;
   size_t zeroPadSize = 3*fourierSize;

   const RealVector& centreFreqs = realVector( 400 );
   double deltaRange = 100;
   size_t numFreqs = 100;
   const double freqDelta = deltaRange / numFreqs;

   SamplingInfo samplingInfo;
   Synthesizer::SineGenerator sineGen( samplingInfo );

   RealVector relMaxY;
   RealVector diffX;

   for ( size_t iCentreFreq = 0; iCentreFreq < centreFreqs.size(); ++iCentreFreq )
   {
      for ( size_t iFreq = 0; iFreq < numFreqs; ++iFreq )
      {
         double frequency = centreFreqs[ iCentreFreq ] + freqDelta * iFreq;
         sineGen.setFrequency( frequency );
         RawPcmData::Ptr data = sineGen.generate( fourierSize );

         WaveAnalysis::SpectralReassignmentTransform transform( samplingInfo, fourierSize, zeroPadSize, 2 );
         WaveAnalysis::StftData::Ptr stftData = transform.execute( *data );
         const WaveAnalysis::SrSpectrum& spec = stftData->getSrSpectrum( 0 );

         const RealVector& x = spec.getFrequencies();
         RealVector&& y = spec.getMagnitude();

         y /= Utils::getMaxValue( y );
         RealVector deltaX = x - frequency;
         // msg << Msg::Info << deltaX << Msg::EndReq;

         relMaxY.insert( relMaxY.end(), y.begin(), y.end() );
         diffX.insert( diffX.end(), deltaX.begin(), deltaX.end() );
      }
   }

   SortCache relYSc( diffX );
   const RealVector& relMaxYSorted = relYSc.applyTo( relMaxY );
   const RealVector& relDiffXSorted = relYSc.applyTo( diffX );

   Math::Log10Function log10;

   gPlotFactory().createPlot( "envelope" );
   gPlotFactory().createGraph( relDiffXSorted, relMaxYSorted );

   // Create envelope by requiring linear interpolation is always above curve.
   size_t nEnvelopeSamples = 500;

   RealVector linearGrid = Utils::createRangeReal( -1000, 1000, nEnvelopeSamples );
   RealVector zeros = RealVector( nEnvelopeSamples, 0 );

   gPlotFactory().createScatter( linearGrid, zeros, Plotting::MarkerDrawAttr( Qt::red ) );


   gPlotFactory().createPlot( "envelopLog" );
   gPlotFactory().createGraph( relDiffXSorted, log10.evalMany( relMaxYSorted ) );



   // RealVector fCorr = spec.getFrequencyCorrections();
   // for ( size_t i = 0; i < spec.getFrequencies().size(); ++i )
   // {
   //    fCorr[ i ] /= spec.getFrequency( i );
   // }


   // Math::Log10Function log10Fct;

   // gPlotFactory().createPlot( "plot1" );
   // gPlotFactory().createGraph( x, log10Fct.evalMany( y ), Qt::blue );
   // gPlotFactory().createScatter( x, log10Fct.evalMany( y ) );
   // gPlotFactory().createGraph( x, log10Fct.evalMany( fCorr ), Qt::green );
   // gPlotFactory().createScatter( x, log10Fct.evalMany( fCorr ), Plotting::MarkerDrawAttr( Qt::red ) );

   // msg << Msg::Info << "Number of spectra in STFT: " << stftData->getNumSpectra() << Msg::EndReq;
   // for ( size_t iSpec = 0; iSpec < stftData->getNumSpectra(); ++iSpec )
   // {
   //    const WaveAnalysis::WindowLocation* windowLoc = stftData->getSpectrum( iSpec ).getWindowLocation();
   //    msg << Msg::Info << "WindowLocation: [" << windowLoc->getFirstSample() << ", " << windowLoc->getLastSample() << "]" << Msg::EndReq;
   // }



}
コード例 #8
0
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Constructor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MultiLayerPerceptron::MultiLayerPerceptron( size_t numInputNodes, size_t numOutputNodes, const std::vector< size_t >& hiddenLayerStructure, bool useBiasNodes ) :
   m_input( numInputNodes ),
   m_output( numOutputNodes ),
   m_deltaEInput( numInputNodes ),
   m_deltaEOutput( numOutputNodes ),
   m_useBiasNodes( useBiasNodes ),
   m_numWeights( 0 )
{
   assert( numInputNodes > 0 && numOutputNodes > 0 );

   /// Initialise neuron quantities.
   for ( auto it = hiddenLayerStructure.begin(); it != hiddenLayerStructure.end(); ++it )
   {
      assert( *it > 0 );
      m_y.push_back( RealVector( *it ) );
      m_dfdy.push_back( RealVector( *it ) );

      m_x.push_back( RealVector( *it ) );
      m_deltaE.push_back( RealVector( *it ) );
   }

   /// Initialise first layer weights.
   size_t numFirstLayerTargetNeurons = m_y.size() > 0 ? m_y[0].size() : m_output.size();
   m_weights.push_back( std::vector< RealVector >( m_input.size(), RealVector( numFirstLayerTargetNeurons, 1 ) ) );

   /// Initialise hidden layer weights.
   for ( int i = 0; i < static_cast< int >( m_y.size() ) - 1; ++i )
   {
      size_t nNeurons = m_y[ i ].size();
      size_t nNeuronsNext = m_y[ i + 1 ].size();
      m_weights.push_back( std::vector< RealVector >( nNeurons, RealVector( nNeuronsNext, 1 ) ) );
   }

   /// Initialse final layer weights.
   if ( hiddenLayerStructure.size() != 0 )
   {
      m_weights.push_back( std::vector< RealVector >( m_y.back().size(), RealVector( m_output.size(), 1 ) ) );
   }

   /// Initialise Bias nodes.
   if ( useBiasNodes )
   {
      for ( size_t i = 0; i < m_x.size(); ++i )
      {
         m_x[ i ].push_back( 1 );
         m_deltaE[ i ].push_back( 0 );
      }

      m_deltaEOutput.push_back( 0 );
      m_input.push_back( 1 );

      for ( size_t iLayer = 0; iLayer < m_weights.size(); ++iLayer )
      {
         m_weights[ iLayer ].push_back( m_weights[ iLayer ][ 0 ] );

         /// Initialise bias weights with 0
         for ( size_t i = 0; i < m_weights[ iLayer ].back().size(); ++i )
         {
            m_weights[ iLayer ].back()[ i ] = 0;
         }
      }
   }

   m_weightDerivatives = m_weights;

   /// Count the number of weights.
   for ( size_t i = 0; i < m_weights.size(); ++i )
   {
      for ( size_t j = 0; j < m_weights[ i ].size(); ++j )
      {
         m_numWeights += m_weights[ i ][ j ].size();
      }
   }

}
コード例 #9
0
ファイル: YPlus.cpp プロジェクト: hsimilli/coolfluid3
void YPlus::execute()
{
  Mesh& mesh = this->mesh();

  // Geometry data
  const Field& coords = mesh.geometry_fields().coordinates();
  const Uint nb_nodes = coords.size();
  const Uint dim = coords.row_size();

  // Velocity data
  const Field& velocity_field = common::find_component_recursively_with_tag<Field>(mesh, options().value<std::string>("velocity_tag"));
  const auto velocity_dict_handle = Handle<Dictionary const>(velocity_field.parent());
  cf3_assert(velocity_dict_handle != nullptr);
  const Dictionary& velocity_dict = *velocity_dict_handle;
  const Uint vel_offset = velocity_field.descriptor().offset("Velocity");

  // initialize if needed
  auto volume_node_connectivity = Handle<NodeConnectivity>(mesh.get_child("volume_node_connectivity"));
  if(m_normals.empty())
  {
    // Node-to-element connectivity for the volume elements
    volume_node_connectivity = mesh.create_component<NodeConnectivity>("volume_node_connectivity");
    std::vector< Handle<Entities const> > volume_entities;
    for(const mesh::Elements& elements : common::find_components_recursively_with_filter<mesh::Elements>(mesh, IsElementsVolume()))
    {
      volume_entities.push_back(elements.handle<Entities const>());
    }
    volume_node_connectivity->initialize(nb_nodes, volume_entities);

    mesh.geometry_fields().create_field("wall_velocity_gradient_nodal").add_tag("wall_velocity_gradient_nodal");
    Dictionary& wall_P0 = *mesh.create_component<DiscontinuousDictionary>("wall_P0");

    m_normals.clear();
    for(const Handle<Region>& region : regions())
    {
      for(mesh::Elements& wall_entity : common::find_components_recursively_with_filter<mesh::Elements>(*region, IsElementsSurface()))
      {
        const Uint nb_elems = wall_entity.size();
        const auto& geom_conn = wall_entity.geometry_space().connectivity();
        const ElementType& etype = wall_entity.element_type();
        const Uint element_nb_nodes = etype.nb_nodes();

        m_normals.push_back(std::vector<RealVector>(nb_elems, RealVector(dim)));

        RealMatrix elem_coords(element_nb_nodes, dim);
        for(Uint elem_idx = 0; elem_idx != nb_elems; ++elem_idx)
        {
          const Connectivity::ConstRow conn_row = geom_conn[elem_idx];
          fill(elem_coords, coords, conn_row);
          RealVector normal(dim);
          etype.compute_normal(elem_coords, m_normals.back()[elem_idx]);
          m_normals.back()[elem_idx] /= m_normals.back()[elem_idx].norm();
        }

        wall_entity.create_component<FaceConnectivity>("wall_face_connectivity")->initialize(*volume_node_connectivity);
        wall_entity.create_space("cf3.mesh.LagrangeP0."+wall_entity.element_type().shape_name(),wall_P0);
      }
    }
    wall_P0.build();         // to tell the dictionary that all spaces have been added
    mesh.update_structures(); // to tell the mesh there is a new dictionary added manually
    wall_P0.create_field("wall_velocity_gradient").add_tag("wall_velocity_gradient");
  }

  // Create the y+ field in the geometry dictionary
  if(common::find_component_ptr_with_tag(mesh.geometry_fields(), "yplus") == nullptr)
  {
    mesh.geometry_fields().create_field("yplus").add_tag("yplus");
  }

  // Compute shear stress
  Uint surface_idx = 0;
  Dictionary& wall_P0 = *Handle<mesh::Dictionary>(mesh.get_child_checked("wall_P0"));
  Field& wall_velocity_gradient_field = *Handle<Field>(wall_P0.get_child_checked("wall_velocity_gradient"));
  for(const Handle<Region>& region : regions())
  {
    for(const mesh::Elements& elements : common::find_components_recursively_with_filter<mesh::Elements>(*region, IsElementsSurface()))
    {
      const Uint nb_elements = elements.geometry_space().connectivity().size();
      cf3_assert(elements.element_type().nb_faces() == 1);
      const auto& face_connectivity = *Handle<FaceConnectivity const>(elements.get_child_checked("wall_face_connectivity"));
      const auto& wall_conn = elements.space(wall_P0).connectivity();
      for(Uint surface_elm_idx = 0; surface_elm_idx != nb_elements; ++surface_elm_idx)
      {
        if(face_connectivity.has_adjacent_element(surface_elm_idx, 0))
        {
          const Uint wall_field_idx = wall_conn[surface_elm_idx][0];
          // Get the wall normal vector
          const RealVector& normal = m_normals[surface_idx][surface_elm_idx];
          RealVector3 normal3;
          normal3[0] = normal[0];
          normal3[1] = normal[1];
          normal3[2] = dim == 3 ? normal[2] : 0.;

          // The connected volume element
          NodeConnectivity::ElementReferenceT connected = face_connectivity.adjacent_element(surface_elm_idx, 0);
          const mesh::Entities& volume_entities = *face_connectivity.node_connectivity().entities()[connected.first];
          const Uint volume_elem_idx = connected.second;
          const auto& velocity_conn = volume_entities.space(velocity_dict).connectivity();
          const auto& velocity_sf = volume_entities.space(velocity_dict).shape_function();
          const auto& geom_conn = volume_entities.geometry_space().connectivity();
          const ElementType& volume_etype = volume_entities.element_type();

          const Uint nb_vel_nodes = velocity_sf.nb_nodes();
          const RealVector centroid_mapped_coord = 0.5*(velocity_sf.local_coordinates().colwise().minCoeff() + velocity_sf.local_coordinates().colwise().maxCoeff());
          RealMatrix elem_coords(geom_conn.row_size(), dim);
          fill(elem_coords, coords, geom_conn[volume_elem_idx]);

          RealVector tangential_velocity(nb_vel_nodes); // For every node, the component of the velocity tangential to the wall
          RealVector3 v3;
          for(Uint i = 0; i != nb_vel_nodes; ++i)
          {
            Eigen::Map<RealVector const> v(&velocity_field[velocity_conn[volume_elem_idx][i]][vel_offset], dim);
            v3[0] = v[0];
            v3[1] = v[1];
            v3[2] = dim == 3 ? v[2] : 0.;
            tangential_velocity[i] = v3.cross(normal3).norm();
          }
          wall_velocity_gradient_field[wall_field_idx][0] = fabs((volume_etype.jacobian(centroid_mapped_coord, elem_coords).inverse() * velocity_sf.gradient(centroid_mapped_coord) * tangential_velocity).dot(-normal));
        }
      }
      ++surface_idx;
    }
  }

  wall_velocity_gradient_field.synchronize();

  // Compute a nodal version of the wall velocity gradient
  const auto& wall_node_connectivity = *Handle<NodeConnectivity>(mesh.get_child_checked("wall_node_connectivity"));
  Field& wall_velocity_gradient_field_nodal = *Handle<Field>(mesh.geometry_fields().get_child_checked("wall_velocity_gradient_nodal"));
  for(Uint node_idx = 0; node_idx != nb_nodes; ++node_idx)
  {
    Uint nb_connected_elems = 0;
    wall_velocity_gradient_field_nodal[node_idx][0] = 0;
    for(const NodeConnectivity::ElementReferenceT elref : wall_node_connectivity.node_element_range(node_idx))
    {
      const Uint wall_field_idx = wall_node_connectivity.entities()[elref.first]->space(wall_P0).connectivity()[elref.second][0];
      wall_velocity_gradient_field_nodal[node_idx][0] += wall_velocity_gradient_field[wall_field_idx][0];
      ++nb_connected_elems;
    }
    if(nb_connected_elems != 0)
    {
      wall_velocity_gradient_field_nodal[node_idx][0] /= static_cast<Real>(nb_connected_elems);
    }
  }


  // Set Yplus
  Field& yplus_field = *Handle<Field>(mesh.geometry_fields().get_child_checked("yplus"));
  const Field& wall_distance_field = *Handle<Field>(mesh.geometry_fields().get_child_checked("wall_distance"));
  const auto& node_to_wall_element = *Handle<common::Table<Uint>>(mesh.get_child_checked("node_to_wall_element"));
  const Real nu = physical_model().options().value<Real>("kinematic_viscosity");
  for(Uint node_idx = 0; node_idx != nb_nodes; ++node_idx)
  {
    yplus_field[node_idx][0] = 0;
    if(node_to_wall_element[node_idx][0] != 0)
    {
      const Entities& wall_entities = *wall_node_connectivity.entities()[node_to_wall_element[node_idx][1]];
      const Uint wall_field_idx = wall_entities.space(wall_P0).connectivity()[node_to_wall_element[node_idx][2]][0];
      yplus_field[node_idx][0] = wall_distance_field[node_idx][0] * sqrt(nu*wall_velocity_gradient_field[wall_field_idx][0]) / nu;
    }
    else
    {
      yplus_field[node_idx][0] = wall_distance_field[node_idx][0] * sqrt(nu*wall_velocity_gradient_field_nodal[node_to_wall_element[node_idx][1]][0]) / nu;
    }
  }
}