ABLATE Source Documentation  0.12.36
constantVolumeIgnitionReactorTemperatureThreshold.hpp
1 /* =====================================================================================
2 TChem version 2.0
3 Copyright (2020) NTESS
4 https://github.com/sandialabs/TChem
5 
6 Copyright 2020 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
7 Under the terms of Contract DE-NA0003525 with NTESS, the U.S. Government retains
8 certain rights in this software.
9 
10 This file is part of TChem. TChem is open source software: you can redistribute it
11 and/or modify it under the terms of BSD 2-Clause License
12 (https://opensource.org/licenses/BSD-2-Clause). A copy of the licese is also
13 provided under the main directory
14 
15 Questions? Contact Cosmin Safta at <csafta@sandia.gov>, or
16  Kyungjoo Kim at <kyukim@sandia.gov>, or
17  Oscar Diaz-Ibarra at <odiazib@sandia.gov>
18 
19 Sandia National Laboratories, Livermore, CA, USA
20 ===================================================================================== */
21 
22 #ifndef ABLATELIBRARY_TCHEM_CONSTANTVOLUMEIGNITIONREACTORTEMPERATURETHRESHOLD_HPP
23 #define ABLATELIBRARY_TCHEM_CONSTANTVOLUMEIGNITIONREACTORTEMPERATURETHRESHOLD_HPP
24 
25 #include <TChem_ConstantVolumeIgnitionReactor.hpp>
26 #include "TChem_KineticModelData.hpp"
27 #include "TChem_Util.hpp"
28 
29 namespace ablate::eos::tChem {
30 template <typename PolicyType, typename ValueType, typename DeviceType>
31 void ConstantVolumeIgnitionReactor_TemplateRun(
32  const std::string& profile_name, const ValueType& dummyValueType,
34  const PolicyType& policy,
36  const bool solve_tla, const real_type theta_tla,
38  const Tines::value_type_1d_view<real_type, DeviceType>& tol_newton, const Tines::value_type_2d_view<real_type, DeviceType>& tol_time, const Tines::value_type_2d_view<real_type, DeviceType>& fac,
39  const Tines::value_type_1d_view<time_advance_type, DeviceType>& tadv,
40  // /// state (nSample, nSpec+1)
41  const Tines::value_type_2d_view<real_type, DeviceType>& state,
42  // /// state_z (nSample, nSpec, nReac)
43  const Tines::value_type_3d_view<real_type, DeviceType>& state_z,
44  // /// output
45  const Tines::value_type_1d_view<real_type, DeviceType>& t_out, const Tines::value_type_1d_view<real_type, DeviceType>& dt_out, const Tines::value_type_2d_view<real_type, DeviceType>& state_out,
46  const Tines::value_type_3d_view<real_type, DeviceType>& state_z_out,
47  // /// const data from kinetic model
48  const Tines::value_type_1d_view<KineticModelConstData<DeviceType>, DeviceType>& kmcds, double thresholdTemperature) {
49  Kokkos::Profiling::pushRegion(profile_name);
50 
51  using policy_type = PolicyType;
52  using value_type = ValueType;
53  using device_type = DeviceType;
54 
55  using real_type_0d_view_type = Tines::value_type_0d_view<real_type, device_type>;
56  using real_type_1d_view_type = Tines::value_type_1d_view<real_type, device_type>;
57  using real_type_2d_view_type = Tines::value_type_2d_view<real_type, device_type>;
58 
60  auto kmcd_host = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), Kokkos::subview(kmcds, 0));
61 
62  const ordinal_type level = 1;
63  const ordinal_type per_team_extent = ConstantVolumeIgnitionReactor::getWorkSpaceSize(solve_tla, kmcd_host());
64 
65  Kokkos::parallel_for(
66  profile_name, policy, KOKKOS_LAMBDA(const typename policy_type::member_type& member) {
67  const ordinal_type i = member.league_rank();
68  const real_type zero(0);
69 
70  const auto kmcd_at_i = (kmcds.extent(0) == 1 ? kmcds(0) : kmcds(i));
71  const auto tadv_at_i = tadv(i);
72  const real_type t_end = tadv_at_i._tend;
73  const real_type_0d_view_type t_out_at_i = Kokkos::subview(t_out, i);
74  if (t_out_at_i() < t_end) {
75  const real_type_1d_view_type state_at_i = Kokkos::subview(state, i, Kokkos::ALL());
76  const real_type_1d_view_type state_out_at_i = Kokkos::subview(state_out, i, Kokkos::ALL());
77  const real_type_1d_view_type fac_at_i = Kokkos::subview(fac, i, Kokkos::ALL());
78 
79  const real_type_0d_view_type dt_out_at_i = Kokkos::subview(dt_out, i);
80  Scratch<real_type_1d_view_type> work(member.team_scratch(level), per_team_extent);
81 
82  Impl::StateVector<real_type_1d_view_type> sv_at_i(kmcd_at_i.nSpec, state_at_i);
83  Impl::StateVector<real_type_1d_view_type> sv_out_at_i(kmcd_at_i.nSpec, state_out_at_i);
84  TCHEM_CHECK_ERROR(!sv_at_i.isValid(), "Error: input state vector is not valid");
85  TCHEM_CHECK_ERROR(!sv_out_at_i.isValid(), "Error: input state vector is not valid");
86  {
87  const ordinal_type jacobian_interval = tadv_at_i._jacobian_interval;
88  const ordinal_type max_num_newton_iterations = tadv_at_i._max_num_newton_iterations;
89  const ordinal_type max_num_time_iterations = tadv_at_i._num_time_iterations_per_interval;
90  const ordinal_type max_num_outer_time_iterations = tadv_at_i._num_outer_time_iterations_per_interval;
91 
92  const real_type dt_in = tadv_at_i._dt, dt_min = tadv_at_i._dtmin, dt_max = tadv_at_i._dtmax;
93  const real_type t_beg = tadv_at_i._tbeg;
94 
95  const real_type temperature = sv_at_i.Temperature();
96 
97  // only bother to integrate this point in the ode if the temperature is greater than thresholdTemperature
98  if (temperature > thresholdTemperature) {
99  const real_type density = sv_at_i.Density();
100  const real_type_1d_view_type Ys = sv_at_i.MassFractions();
101 
102  const real_type_0d_view_type temperature_out(sv_out_at_i.TemperaturePtr());
103  const real_type_0d_view_type pressure_out(sv_out_at_i.PressurePtr());
104  const real_type_1d_view_type Ys_out = sv_out_at_i.MassFractions();
105  const real_type_0d_view_type density_out(sv_out_at_i.DensityPtr());
106 
107  const ordinal_type m = kmcd_at_i.nSpec + 1;
108  auto wptr = work.data();
109  const real_type_1d_view_type vals(wptr, m);
110  wptr += m;
111  const real_type_1d_view_type vals_out(wptr, m);
112  wptr += m;
113  const real_type_1d_view_type ww(wptr, work.extent(0) - (wptr - work.data()));
114 
117 
119  ::TChem::ConstantVolumeIgnitionReactor ::packToValues(member, temperature, Ys, vals);
120  member.team_barrier();
121 
122  using constant_volume_ignition_type = Impl::ConstantVolumeIgnitionReactor<value_type, device_type>;
123 
124  real_type t_cur(t_out_at_i());
125  for (ordinal_type iter = 0; iter < max_num_outer_time_iterations; ++iter) {
127  constant_volume_ignition_type ::team_invoke(member,
128  jacobian_interval,
129  max_num_newton_iterations,
130  max_num_time_iterations,
131  tol_newton,
132  tol_time,
133  fac_at_i,
134  dt_in,
135  dt_min,
136  dt_max,
137  t_beg,
138  t_end,
139  density,
140  vals,
141  t_out_at_i,
142  dt_out_at_i,
143  vals_out,
144  ww,
145  kmcd_at_i);
146 
148  const real_type dt_tla = t_out_at_i() - t_cur;
149  if (solve_tla && dt_tla > zero) {
150  auto wtmp = ww.data();
151  const ordinal_type n = kmcd_at_i.nReac;
152 
154  const real_type temperature_a = vals(0), temperature_b = vals_out(0);
155 
157  using problem_type = Impl::ConstantVolumeIgnitionReactor_Problem<value_type, device_type>;
158 
160  real_type_2d_view_type J_a(wtmp, m, m);
161  wtmp += J_a.span();
162  real_type_2d_view_type J_b(wtmp, m, m);
163  wtmp += J_b.span();
164  {
165  problem_type problem;
166  problem._density = density;
167  problem._fac = fac_at_i;
168  problem._kmcd = kmcd_at_i;
169 
170  real_type_1d_view_type pw(wtmp, problem.getWorkSpaceSize());
171  problem._work = pw;
172 
173  problem.computeJacobian(member, vals, J_a);
174  problem.computeJacobian(member, vals_out, J_b);
175  }
176 
178  real_type pressure_computed_a(0), pressure_computed_b(0);
179  const auto Ys_vals_a = Kokkos::subview(vals, Kokkos::make_pair(1, m));
180  const auto Ys_vals_b = Kokkos::subview(vals_out, Kokkos::make_pair(1, m));
181  {
182  using molar_weights = Impl::MolarWeights<real_type, device_type>;
183  const real_type Wmix_a = molar_weights::team_invoke(member, Ys_vals_a, kmcd_at_i);
184  const real_type Wmix_b = molar_weights::team_invoke(member, Ys_vals_b, kmcd_at_i);
185  member.team_barrier();
186  pressure_computed_a = density * kmcd_at_i.Runiv * temperature_a / Wmix_a;
187  pressure_computed_b = density * kmcd_at_i.Runiv * temperature_b / Wmix_b;
188  }
189 
191  {
192  using tla_type = Impl::TangentLinearApproximationIgnitionDelayTime<real_type, device_type, Impl::ConstantVolumeIgnitionReactorTangetLinearApproximationSourceTerm>;
193 
194  const ordinal_type wsize_tla = tla_type::getWorkSpaceSize(kmcd_at_i);
195  auto state_z_at_i = Kokkos::subview(state_z, i, Kokkos::ALL(), Kokkos::ALL());
196  auto state_z_out_at_i = Kokkos::subview(state_z_out, i, Kokkos::ALL(), Kokkos::ALL());
197  real_type_1d_view_type work_tla(wtmp, wsize_tla);
198  tla_type ::team_invoke(member,
199  theta_tla,
200  dt_tla,
201  density,
202  pressure_computed_a,
203  pressure_computed_b,
204  temperature_a,
205  temperature_b,
206  Ys_vals_a,
207  Ys_vals_b,
208  J_a,
209  J_b,
210  state_z_at_i,
211  state_z_out_at_i,
212  work_tla,
213  kmcd_at_i);
214 
216  if (state_z.data() != state_z_out.data()) {
217  Kokkos::parallel_for(Kokkos::TeamVectorRange(member, m * n), [=](const ordinal_type& kk) {
218  const ordinal_type k0 = kk / n, k1 = kk % n;
219  state_z_at_i(k0, k1) = state_z_out_at_i(k0, k1);
220  });
221  member.team_barrier();
222  }
223  }
224  }
225 
227  if (vals.data() != vals_out.data()) {
228  Kokkos::parallel_for(Kokkos::TeamVectorRange(member, m), [=](const ordinal_type& i) { vals(i) = vals_out(i); });
229  member.team_barrier();
230  }
231 
233  t_cur = t_out_at_i();
234  }
235 
236  member.team_barrier();
237  ::TChem::ConstantVolumeIgnitionReactor ::unpackFromValues(member, vals_out, temperature_out, Ys_out);
238  member.team_barrier();
239 
240  // update density and pressure with out data
241  {
242  const real_type Wmix = Impl::MolarWeights<real_type, device_type>::team_invoke(member, Ys_out, kmcd_at_i);
243 
244  Kokkos::single(Kokkos::PerTeam(member), [&]() {
245  density_out() = density; // density is constant
246  pressure_out() = density * kmcd_at_i.Runiv * temperature_out() / Wmix;
247  });
248  member.team_barrier();
249  }
250  } else {
251  for (ordinal_type s = 0; s < sv_at_i.size(); ++s) {
252  state_out_at_i[s] = state_at_i[s];
253  }
254  }
255  }
256  }
257  });
258  Kokkos::Profiling::popRegion();
259 }
260 
262  public:
269  static void runDeviceBatch(
270  typename UseThisTeamPolicy<exec_space>::type& policy, const bool& solve_tla, const real_type& theta_tla,
272  const real_type_1d_view& tol_newton, const real_type_2d_view& tol_time, const real_type_2d_view& fac, const time_advance_type_1d_view& tadv, const real_type_2d_view& state,
273  const real_type_3d_view& state_z,
275  const real_type_1d_view& t_out, const real_type_1d_view& dt_out, const real_type_2d_view& state_out, const real_type_3d_view& state_z_out,
277  const Tines::value_type_1d_view<KineticModelConstData<interf_device_type>, interf_device_type>& kmcds, double thresholdTemperature) {
278  const std::string profile_name = "ablate::eos::tChem::IgnitionZeroDTemperatureThreshold::runDeviceBatch::kmcd array";
279  using value_type = real_type;
280 
281  ConstantVolumeIgnitionReactor_TemplateRun(
282  profile_name, value_type(), policy, solve_tla, theta_tla, tol_newton, tol_time, fac, tadv, state, state_z, t_out, dt_out, state_out, state_z_out, kmcds, thresholdTemperature);
283  }
284 };
285 
286 } // namespace ablate::eos::tChem
287 #endif
Definition: constantVolumeIgnitionReactorTemperatureThreshold.hpp:261
static void runDeviceBatch(typename UseThisTeamPolicy< exec_space >::type &policy, const bool &solve_tla, const real_type &theta_tla, const real_type_1d_view &tol_newton, const real_type_2d_view &tol_time, const real_type_2d_view &fac, const time_advance_type_1d_view &tadv, const real_type_2d_view &state, const real_type_3d_view &state_z, const real_type_1d_view &t_out, const real_type_1d_view &dt_out, const real_type_2d_view &state_out, const real_type_3d_view &state_z_out, const Tines::value_type_1d_view< KineticModelConstData< interf_device_type >, interf_device_type > &kmcds, double thresholdTemperature)
Definition: constantVolumeIgnitionReactorTemperatureThreshold.hpp:269