27 #ifndef OOMPH_PML_HELMHOLTZ_ELEMENTS_HEADER
28 #define OOMPH_PML_HELMHOLTZ_ELEMENTS_HEADER
33 #include <oomph-lib-config.h>
40 #include "../generic/nodes.h"
41 #include "../generic/Qelements.h"
42 #include "../generic/oomph_utilities.h"
43 #include "../generic/pml_meshes.h"
44 #include "../generic/projection.h"
45 #include "../generic/pml_mapping_functions.h"
59 template<
unsigned DIM>
67 std::complex<double>&
f);
93 return std::complex<unsigned>(0, 1);
110 "Please set pointer to k_squared using access fct to pointer!",
142 const unsigned& nplot)
const
149 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
161 file_out << u.real() << std::endl;
166 file_out << u.imag() << std::endl;
172 std::stringstream error_stream;
173 error_stream <<
"PML Helmholtz elements only store 2 fields (real "
175 <<
"so i must be 0 or 1 rather "
176 <<
"than " <<
i << std::endl;
189 std::ofstream& file_out,
191 const unsigned& nplot,
205 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
233 std::stringstream error_stream;
234 error_stream <<
"PML Helmholtz elements only store 2 fields (real "
236 <<
"so i must be 0 or 1 rather "
237 <<
"than " <<
i << std::endl;
259 return "Imaginary part";
265 std::stringstream error_stream;
266 error_stream <<
"PML Helmholtz elements only store 2 fields (real "
268 <<
"so i must be 0 or 1 rather "
269 <<
"than " <<
i << std::endl;
284 const unsigned n_plot = 5;
290 void output(std::ostream& outfile,
const unsigned& n_plot);
299 std::ostream& outfile,
302 const unsigned& nplot);
312 const unsigned& n_plot);
320 const unsigned& n_plot);
325 const unsigned n_plot = 5;
331 void output(FILE* file_pt,
const unsigned& n_plot);
336 const unsigned& n_plot,
342 std::ostream& outfile,
343 const unsigned& n_plot,
348 "There is no time-dependent output_fct() for PMLHelmholtz elements.",
361 const unsigned& n_plot,
371 const unsigned& n_plot,
390 "There is no time-dependent compute_error() for PMLHelmholtz elements.",
418 std::complex<double>&
source)
const
423 source = std::complex<double>(0.0, 0.0);
438 values_to_pin.resize(2);
440 values_to_pin[0] = 0;
441 values_to_pin[1] = 1;
450 const unsigned n_node =
nnode();
461 const std::complex<double>
zero(0.0, 0.0);
462 for (
unsigned j = 0;
j <
DIM;
j++)
468 for (
unsigned l = 0; l < n_node; l++)
471 const std::complex<double> u_value(
475 for (
unsigned j = 0;
j <
DIM;
j++)
477 flux[
j] += u_value * dpsidx(l,
j);
509 const unsigned n_node =
nnode();
518 std::complex<double> interpolated_u(0.0, 0.0);
525 for (
unsigned l = 0; l < n_node; l++)
528 const std::complex<double> u_value(
532 interpolated_u += u_value * psi[l];
534 return interpolated_u;
549 Vector<std::complex<double>>& pml_laplace_factor,
550 std::complex<double>& pml_k_squared_factor)
554 for (
unsigned k = 0;
k <
DIM;
k++)
562 for (
unsigned k = 0;
k <
DIM;
k++)
576 for (
unsigned k = 0;
k <
DIM;
k++)
582 nu[
k], pml_width[
k], k_squared_local,
alpha());
596 pml_laplace_factor[0] = pml_gamma[1] / pml_gamma[0];
597 pml_laplace_factor[1] = pml_gamma[0] / pml_gamma[1];
598 pml_k_squared_factor = pml_gamma[0] * pml_gamma[1];
602 pml_laplace_factor[0] = pml_gamma[1] * pml_gamma[2] / pml_gamma[0];
603 pml_laplace_factor[1] = pml_gamma[0] * pml_gamma[2] / pml_gamma[1];
604 pml_laplace_factor[2] = pml_gamma[0] * pml_gamma[1] / pml_gamma[2];
605 pml_k_squared_factor = pml_gamma[0] * pml_gamma[1] * pml_gamma[2];
612 for (
unsigned k = 0;
k <
DIM;
k++)
614 pml_laplace_factor[
k] = std::complex<double>(1.0, 0.0);
617 pml_k_squared_factor = std::complex<double>(1.0, 0.0);
651 std::list<std::pair<unsigned long, unsigned>>& dof_lookup_list)
const
654 std::pair<unsigned, unsigned> dof_lookup;
657 unsigned n_node = this->
nnode();
660 for (
unsigned n = 0;
n < n_node;
n++)
667 if (local_eqn_number >= 0)
671 dof_lookup.first = this->
eqn_number(local_eqn_number);
672 dof_lookup.second = 0;
675 dof_lookup_list.push_front(dof_lookup);
682 if (local_eqn_number >= 0)
686 dof_lookup.first = this->
eqn_number(local_eqn_number);
687 dof_lookup.second = 1;
690 dof_lookup_list.push_front(dof_lookup);
704 DShape& dtestdx)
const = 0;
714 DShape& dtestdx)
const = 0;
721 const unsigned& flag);
751 template<
unsigned DIM,
unsigned NNODE_1D>
792 void output(std::ostream& outfile,
const unsigned& n_plot)
804 const unsigned& n_plot)
815 const unsigned& n_plot)
831 void output(FILE* file_pt,
const unsigned& n_plot)
840 const unsigned& n_plot,
854 const unsigned& n_plot,
858 outfile, phi, n_plot, exact_soln_pt);
868 const unsigned& n_plot,
872 outfile, phi, n_plot, exact_soln_pt);
880 const unsigned& n_plot,
885 outfile, n_plot, time, exact_soln_pt);
918 template<
unsigned DIM,
unsigned NNODE_1D>
927 const double J = this->dshape_eulerian(
s, psi, dpsidx);
944 template<
unsigned DIM,
unsigned NNODE_1D>
953 const double J = this->dshape_eulerian_at_knot(ipt, psi, dpsidx);
974 template<
unsigned DIM,
unsigned NNODE_1D>
976 :
public virtual QElement<DIM - 1, NNODE_1D>
993 template<
unsigned NNODE_1D>
1012 template<
class HELMHOLTZ_ELEMENT>
1029 std::stringstream error_stream;
1030 error_stream <<
"PMLHelmholtz elements only store 2 fields so fld = "
1031 << fld <<
" is illegal \n";
1038 unsigned nnod = this->
nnode();
1042 for (
unsigned j = 0;
j < nnod;
j++)
1045 data_values[
j] = std::make_pair(this->
node_pt(
j), fld);
1065 std::stringstream error_stream;
1066 error_stream <<
"PMLHelmholtz elements only store two fields so fld = "
1067 << fld <<
" is illegal\n";
1091 std::stringstream error_stream;
1092 error_stream <<
"PMLHelmholtz elements only store two fields so fld = "
1093 << fld <<
" is illegal.\n";
1098 unsigned n_dim = this->
dim();
1099 unsigned n_node = this->
nnode();
1101 DShape dpsidx(n_node, n_dim), dtestdx(n_node, n_dim);
1102 double J = this->dshape_and_dtest_eulerian_helmholtz(
1103 s, psi, dpsidx,
test, dtestdx);
1111 const unsigned& fld,
1117 std::stringstream error_stream;
1118 error_stream <<
"PMLHelmholtz elements only store two fields so fld = "
1119 << fld <<
" is illegal\n";
1125 std::complex<unsigned> complex_u_nodal_index = this->u_index_helmholtz();
1126 unsigned u_nodal_index = 0;
1129 u_nodal_index = complex_u_nodal_index.real();
1133 u_nodal_index = complex_u_nodal_index.imag();
1138 unsigned n_node = this->
nnode();
1142 this->
shape(s, psi);
1145 double interpolated_u = 0.0;
1148 for (
unsigned l = 0; l < n_node; l++)
1150 interpolated_u += this->
nodal_value(t, l, u_nodal_index) * psi[l];
1152 return interpolated_u;
1162 std::stringstream error_stream;
1163 error_stream <<
"PMLHelmholtz elements only store two fields so fld = "
1164 << fld <<
" is illegal\n";
1169 return this->
nnode();
1179 std::stringstream error_stream;
1180 error_stream <<
"PMLHelmholtz elements only store two fields so fld = "
1181 << fld <<
" is illegal\n";
1186 std::complex<unsigned> complex_u_nodal_index = this->u_index_helmholtz();
1187 unsigned u_nodal_index = 0;
1190 u_nodal_index = complex_u_nodal_index.real();
1194 u_nodal_index = complex_u_nodal_index.imag();
1201 void output(std::ostream& outfile,
const unsigned& nplot)
1212 template<
class ELEMENT>
1228 template<
unsigned NNODE_1D>
AnnoyingScalar imag(const AnnoyingScalar &)
Definition: AnnoyingScalar.h:132
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
Definition: pml_mapping_functions.h:66
unsigned ntstorage() const
Definition: nodes.cc:879
FaceGeometry()
Definition: pml_helmholtz_elements.h:1217
FaceGeometry()
Definition: pml_helmholtz_elements.h:1000
FaceGeometry()
Definition: pml_helmholtz_elements.h:981
Definition: elements.h:4998
Definition: elements.h:1313
virtual unsigned nplot_points_paraview(const unsigned &nplot) const
Definition: elements.h:2862
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
double nodal_value(const unsigned &n, const unsigned &i) const
Definition: elements.h:2593
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
Definition: elements.cc:3962
virtual void shape(const Vector< double > &s, Shape &psi) const =0
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Definition: elements.h:1432
unsigned dim() const
Definition: elements.h:2611
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Definition: elements.h:1759
virtual void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &shifted_to_interior=false) const
Definition: elements.h:3148
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Definition: elements.h:1765
double dshape_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsidx) const
Definition: elements.cc:3298
unsigned long eqn_number(const unsigned &ieqn_local) const
Definition: elements.h:704
int local_eqn_number(const unsigned long &ieqn_global) const
Definition: elements.h:726
static DenseMatrix< double > Dummy_matrix
Definition: elements.h:227
TimeStepper *& position_time_stepper_pt()
Return a pointer to the position timestepper.
Definition: nodes.h:1022
Definition: oomph_definitions.h:222
Base class for elements with pml capabilities.
Definition: pml_meshes.h:60
bool Pml_is_enabled
Boolean indicating if element is used in pml mode.
Definition: pml_meshes.h:119
std::vector< bool > Pml_direction_active
Definition: pml_meshes.h:124
Vector< double > Pml_outer_boundary
Definition: pml_meshes.h:134
Vector< double > Pml_inner_boundary
Definition: pml_meshes.h:129
Definition: pml_helmholtz_elements.h:62
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: pml_helmholtz_elements.h:495
PMLHelmholtzSourceFctPt Source_fct_pt
Pointer to source function:
Definition: pml_helmholtz_elements.h:727
void values_to_be_pinned_on_outer_pml_boundary(Vector< unsigned > &values_to_pin)
Definition: pml_helmholtz_elements.h:435
virtual void fill_in_generic_residual_contribution_helmholtz(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Definition: pml_helmholtz_elements.cc:56
void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Dummy, time dependent error checker.
Definition: pml_helmholtz_elements.h:383
void get_flux(const Vector< double > &s, Vector< std::complex< double >> &flux) const
Get flux: flux[i] = du/dx_i for real and imag part.
Definition: pml_helmholtz_elements.h:446
virtual double dshape_and_dtest_eulerian_at_knot_helmholtz(const unsigned &ipt, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const =0
void output(std::ostream &outfile)
Output with default number of plot points.
Definition: pml_helmholtz_elements.h:282
PMLMapping * Pml_mapping_pt
Definition: pml_helmholtz_elements.h:734
virtual void get_source_helmholtz(const unsigned &ipt, const Vector< double > &x, std::complex< double > &source) const
Definition: pml_helmholtz_elements.h:416
PMLHelmholtzSourceFctPt & source_fct_pt()
Access function: Pointer to source function.
Definition: pml_helmholtz_elements.h:400
virtual std::complex< unsigned > u_index_helmholtz() const
Broken assignment operator.
Definition: pml_helmholtz_elements.h:91
virtual void output_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Definition: pml_helmholtz_elements.h:341
virtual double dshape_and_dtest_eulerian_helmholtz(const Vector< double > &s, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const =0
std::string scalar_name_paraview(const unsigned &i) const
Definition: pml_helmholtz_elements.h:250
double k_squared()
Get the square of wavenumber.
Definition: pml_helmholtz_elements.h:104
PMLHelmholtzSourceFctPt source_fct_pt() const
Access function: Pointer to source function. Const version.
Definition: pml_helmholtz_elements.h:406
void compute_pml_coefficients(const unsigned &ipt, const Vector< double > &x, Vector< std::complex< double >> &pml_laplace_factor, std::complex< double > &pml_k_squared_factor)
Definition: pml_helmholtz_elements.h:546
void get_dof_numbers_for_unknowns(std::list< std::pair< unsigned long, unsigned >> &dof_lookup_list) const
Definition: pml_helmholtz_elements.h:650
PMLHelmholtzEquations(const PMLHelmholtzEquations &dummy)=delete
Broken copy constructor.
void scalar_value_fct_paraview(std::ofstream &file_out, const unsigned &i, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt) const
Definition: pml_helmholtz_elements.h:188
void compute_norm(double &norm)
Compute norm of fe solution.
Definition: pml_helmholtz_elements.cc:808
void output_imag_fct(std::ostream &outfile, const double &phi, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Definition: pml_helmholtz_elements.cc:675
void output_real(std::ostream &outfile, const double &phi, const unsigned &n_plot)
Definition: pml_helmholtz_elements.cc:384
void output(FILE *file_pt)
C_style output with default number of plot points.
Definition: pml_helmholtz_elements.h:323
static BermudezPMLMapping Default_pml_mapping
Definition: pml_helmholtz_elements.h:635
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector (wrapper)
Definition: pml_helmholtz_elements.h:484
PMLHelmholtzEquations()
Constructor.
Definition: pml_helmholtz_elements.h:70
void(* PMLHelmholtzSourceFctPt)(const Vector< double > &x, std::complex< double > &f)
Definition: pml_helmholtz_elements.h:66
unsigned ndof_types() const
Definition: pml_helmholtz_elements.h:639
PMLMapping *const & pml_mapping_pt() const
Return a pointer to the PML Mapping object (const version)
Definition: pml_helmholtz_elements.h:628
double * Alpha_pt
Pointer to wavenumber complex shift.
Definition: pml_helmholtz_elements.h:724
double * K_squared_pt
Pointer to wave number (must be set!)
Definition: pml_helmholtz_elements.h:730
double *& k_squared_pt()
Get pointer to k_squared.
Definition: pml_helmholtz_elements.h:97
const double & alpha() const
Alpha, wavenumber complex shift.
Definition: pml_helmholtz_elements.h:119
double *& alpha_pt()
Pointer to Alpha, wavenumber complex shift.
Definition: pml_helmholtz_elements.h:125
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Get error against and norm of exact solution.
Definition: pml_helmholtz_elements.cc:728
std::complex< double > interpolated_u_pml_helmholtz(const Vector< double > &s) const
Definition: pml_helmholtz_elements.h:505
unsigned nscalar_paraview() const
Definition: pml_helmholtz_elements.h:133
void output_imag(std::ostream &outfile, const double &phi, const unsigned &n_plot)
Definition: pml_helmholtz_elements.cc:484
static double Default_Physical_Constant_Value
Static default value for the physical constants (initialised to zero)
Definition: pml_helmholtz_elements.h:737
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Definition: pml_helmholtz_elements.cc:564
void scalar_value_paraview(std::ofstream &file_out, const unsigned &i, const unsigned &nplot) const
Definition: pml_helmholtz_elements.h:140
unsigned self_test()
Self-test: Return 0 for OK.
Definition: pml_helmholtz_elements.cc:314
PMLMapping *& pml_mapping_pt()
Return a pointer to the PML Mapping object.
Definition: pml_helmholtz_elements.h:622
void output_real_fct(std::ostream &outfile, const double &phi, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Definition: pml_helmholtz_elements.cc:619
void output_total_real(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt incoming_wave_fct_pt, const double &phi, const unsigned &nplot)
Definition: pml_helmholtz_elements.cc:426
PMLLayerElement()
Definition: pml_helmholtz_elements.h:1235
Definition: pml_meshes.h:48
Definition: pml_mapping_functions.h:46
virtual std::complex< double > gamma(const double &nu_i, const double &pml_width_i, const double &wavenumber_squared, const double &alpha_shift=0.0)=0
Definition: elements.h:3439
Definition: projection.h:183
PMLHelmholtz upgraded to become projectable.
Definition: pml_helmholtz_elements.h:1015
ProjectablePMLHelmholtzElement()
Definition: pml_helmholtz_elements.h:1019
unsigned nvalue_of_field(const unsigned &fld)
Return number of values in field fld: One per node.
Definition: pml_helmholtz_elements.h:1157
double get_field(const unsigned &t, const unsigned &fld, const Vector< double > &s)
Definition: pml_helmholtz_elements.h:1110
unsigned nhistory_values_for_coordinate_projection()
Definition: pml_helmholtz_elements.h:1077
Vector< std::pair< Data *, unsigned > > data_values_of_field(const unsigned &fld)
Definition: pml_helmholtz_elements.h:1024
unsigned nhistory_values_for_projection(const unsigned &fld)
Definition: pml_helmholtz_elements.h:1060
double jacobian_and_shape_of_field(const unsigned &fld, const Vector< double > &s, Shape &psi)
Definition: pml_helmholtz_elements.h:1084
int local_equation(const unsigned &fld, const unsigned &j)
Return local equation number of value j in field fld.
Definition: pml_helmholtz_elements.h:1174
unsigned nfields_for_projection()
Number of fields to be projected: 2 (real and imag part)
Definition: pml_helmholtz_elements.h:1053
void output(std::ostream &outfile, const unsigned &nplot)
Definition: pml_helmholtz_elements.h:1201
Definition: Qelements.h:459
Definition: pml_helmholtz_elements.h:754
QPMLHelmholtzElement(const QPMLHelmholtzElement< DIM, NNODE_1D > &dummy)=delete
Broken copy constructor.
void output_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Definition: pml_helmholtz_elements.h:879
static const unsigned Initial_Nvalue
Definition: pml_helmholtz_elements.h:758
void output(FILE *file_pt, const unsigned &n_plot)
Definition: pml_helmholtz_elements.h:831
void output(FILE *file_pt)
Definition: pml_helmholtz_elements.h:823
void output_real(std::ostream &outfile, const double &phi, const unsigned &n_plot)
Definition: pml_helmholtz_elements.h:802
void output_imag(std::ostream &outfile, const double &phi, const unsigned &n_plot)
Definition: pml_helmholtz_elements.h:813
double dshape_and_dtest_eulerian_at_knot_helmholtz(const unsigned &ipt, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const
Definition: pml_helmholtz_elements.h:946
QPMLHelmholtzElement()
Definition: pml_helmholtz_elements.h:763
double dshape_and_dtest_eulerian_helmholtz(const Vector< double > &s, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const
Definition: pml_helmholtz_elements.h:920
void output(std::ostream &outfile, const unsigned &n_plot)
Definition: pml_helmholtz_elements.h:792
void output_real_fct(std::ostream &outfile, const double &phi, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Definition: pml_helmholtz_elements.h:852
unsigned required_nvalue(const unsigned &n) const
Broken assignment operator.
Definition: pml_helmholtz_elements.h:777
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Definition: pml_helmholtz_elements.h:839
void output(std::ostream &outfile)
Definition: pml_helmholtz_elements.h:784
void output_imag_fct(std::ostream &outfile, const double &phi, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Definition: pml_helmholtz_elements.h:866
unsigned ntstorage() const
Definition: timesteppers.h:601
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
float real
Definition: datatypes.h:10
RealScalar s
Definition: level1_cplx_impl.h:130
char char char int int * k
Definition: level2_impl.h:374
#define DIM
Definition: linearised_navier_stokes_elements.h:44
squared absolute sa ArrayBase::abs2 DOXCOMMA MatrixBase::cwiseAbs2 sa Eigen::abs2 DOXCOMMA Eigen::pow DOXCOMMA ArrayBase::square nearest sa Eigen::floor DOXCOMMA Eigen::ceil DOXCOMMA ArrayBase::round nearest integer not less than the given sa Eigen::floor DOXCOMMA ArrayBase::ceil not a number test
Definition: GlobalFunctions.h:109
void flux(const double &time, const Vector< double > &x, double &flux)
Get flux applied along boundary x=0.
Definition: pretend_melt.cc:59
void exact_soln(const double &time, const Vector< double > &x, Vector< double > &soln)
Definition: unstructured_two_d_curved.cc:301
void source(const Vector< double > &x, Vector< double > &f)
Source function.
Definition: unstructured_two_d_circle.cc:46
int error
Definition: calibrate.py:297
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
list x
Definition: plotDoE.py:28
t
Definition: plotPSD.py:36
Definition: indexed_view.cpp:20
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
void output(std::ostream &outfile, const unsigned &nplot)
Overload output function.
Definition: overloaded_element_body.h:490
EIGEN_DONT_INLINE Scalar zero()
Definition: svd_common.h:232
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2