Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panzer: Time-averaged data #13604

Open
delcmo opened this issue Nov 15, 2024 · 2 comments
Open

Panzer: Time-averaged data #13604

delcmo opened this issue Nov 15, 2024 · 2 comments

Comments

@delcmo
Copy link

delcmo commented Nov 15, 2024

Hello,

We are working on implementing large eddy simulation capability and would need to compute time-averaged quantities. Our plan is to define a nodal fields/variables and closure model on the same model as what is done for initial conditions that initialize a field at the nodes. I am not entirely sure how to add this closure model to the tree and how it should be called at run time. Are there any examples in Panzer that I could rely on to help with the implementation?

Thanks,

Marco

@cgcgcg
Copy link
Contributor

cgcgcg commented Nov 15, 2024

@rppawlo

@delcmo
Copy link
Author

delcmo commented Dec 4, 2024

All,

as a first attempt I wrote a closure model that works on quadrature points to calculate the time average of a given field. The implementation is as below:

//---------------------------------------------------------------------------//
template<class EvalType, class Traits>
void TimeAverage<EvalType, Traits>::evaluateFields(
    typename Traits::EvalData workset)
{
    _dt = workset.step_size;
    if (workset.time > 0.1)
    {
        _atime += _dt;
        _beta = _dt / _atime;
    }
    else
    {
        _atime = 0.0;
        _beta = 0.0;
    }
    auto policy = panzer::HP::inst().teamPolicy<scalar_type, PHX::Device>(
        workset.num_cells);
    Kokkos::parallel_for(this->getName(), policy, *this);
}

//---------------------------------------------------------------------------//
template<class EvalType, class Traits>
void TimeAverage<EvalType, Traits>::operator()(
    const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team) const
{
    const int cell = team.league_rank();
    const int num_point = _field.extent(1);

    Kokkos::parallel_for(
        Kokkos::TeamThreadRange(team, 0, num_point), [&](const int point) {
            if (_atime > 0.0)
            {
                _avg_field(cell, point) = (1.0 - _beta)
                                              * _avg_field(cell, point)
                                          + _beta * _field(cell, point);
            }
            else
            {
                _avg_field(cell, point) = 0.0;
            }
        });
}

I tested the above logic with two approaches.

In a first approach, the closure model is triggered when writing the time-averaged field time_average_velocity_0 to the solution file (Exodus) for every time step. This seems to be working fine on one or multiple cores:
Image
Figure 1: time-averaged velocity and final velocity.

In a second approach, I call the closure model by setting a Response_Functional since ultimately I want to evaluate the time-averaged field after each time step without writing it to the solution file. I face two issues with this approach:

  • when the closure model is called by the Response_Functional, the time and the time step are not set and return nan.
  • the time-averaged field is updated by the Response_Functional but also when writing the field to the solution file (Exodus). The time-averaged field is updated twice for time steps that write the solution to the Exodus file.

After testing these two approaches, I am not sure that a Response is the proper way to update the time-averaged field after each time step.

Thanks,
Marco

@rppawlo rppawlo self-assigned this Dec 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants