9#include <kernel/assembly/asm_traits.hpp> 
   10#include <kernel/lafem/dense_vector.hpp> 
   11#include <kernel/lafem/sparse_matrix_bcsr.hpp> 
   12#include <kernel/lafem/dense_vector_blocked.hpp> 
   13#include <kernel/global/vector.hpp> 
   62    template<
typename DataType_, 
typename IndexType_, 
int dim_>
 
   99      DataType_ 
mu_inf, mu_0, lambda, n, a, reg_eps;
 
  113        mu_0(DataType_(0.01)),
 
  114        lambda(DataType_(1.0)),
 
  117        reg_eps(DataType_(1e-100))
 
  139      template<
typename Space_, 
typename CubatureFactory_>
 
  144        const CubatureFactory_& cubature_factory,
 
  145        const DataType_ scale = DataType_(1)
 
  149        XASSERTM(matrix.
rows() == space.get_num_dofs(), 
"invalid matrix dimensions");
 
  150        XASSERTM(matrix.
columns() == space.get_num_dofs(), 
"invalid matrix dimensions");
 
  151        XASSERTM(convect.
size() == space.get_num_dofs(), 
"invalid vector size");
 
  170        const typename AsmTraits::TrafoType& trafo = space.get_trafo();
 
  173        typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
 
  176        typename AsmTraits::SpaceEvaluator space_eval(space);
 
  179        typename AsmTraits::DofMapping dof_mapping(space);
 
  182        typename AsmTraits::TrafoEvalData trafo_data;
 
  185        typename AsmTraits::SpaceEvalData space_data;
 
  188        typename AsmTraits::CubatureRuleType cubature_rule(Cubature::ctor_factory, cubature_factory);
 
  191        typename MatrixType::ScatterAxpy scatter_matrix(matrix);
 
  194        typename VectorType::GatherAxpy gather_conv(convect);
 
  197        static constexpr int max_local_dofs = AsmTraits::max_local_test_dofs;
 
  202        LocalMatrixType local_matrix;
 
  209        LocalVectorType local_conv_dofs;
 
  212        VectorValue loc_v, mean_v;
 
  215        MatrixValue loc_grad_v;
 
  216        MatrixValue strain_rate_tensor_2;
 
  224        for(
int i(0); i < dim_; ++i)
 
  229        streamdiff_coeffs.
format();
 
  235        for(
typename AsmTraits::CellIterator cell(trafo_eval.begin()); cell != trafo_eval.end(); ++cell)
 
  238          trafo_eval.prepare(cell);
 
  241          space_eval.prepare(trafo_eval);
 
  244          dof_mapping.prepare(cell);
 
  247          const int num_loc_dofs = space_eval.get_num_local_dofs();
 
  250          local_conv_dofs.format();
 
  251          gather_conv(local_conv_dofs, dof_mapping);
 
  260            trafo_eval(trafo_data, barycentre);
 
  261            space_eval(space_data, trafo_data);
 
  265            for(
int i(0); i < num_loc_dofs; ++i)
 
  266              mean_v.axpy(space_data.phi[i].value, local_conv_dofs[i]);
 
  269            const DataType local_norm_v = mean_v.norm_euclid();
 
  272            if(local_norm_v > tol_eps)
 
  275              const DataType local_h = trafo_eval.width_directed(mean_v) * local_norm_v;
 
  278              const DataType local_re = (local_norm_v * local_h) / this->sd_nu;
 
  286          local_matrix.format();
 
  289          for(
int point(0); point < cubature_rule.get_num_points(); ++point)
 
  292            trafo_eval(trafo_data, cubature_rule.get_point(point));
 
  295            space_eval(space_data, trafo_data);
 
  298            const DataType weight = trafo_data.jac_det * cubature_rule.get_weight(point);
 
  301            if(need_conv || need_streamdiff)
 
  304              for(
int i(0); i < num_loc_dofs; ++i)
 
  307                loc_v.axpy(space_data.phi[i].value, local_conv_dofs[i]);
 
  312            for(
int i(0); i < num_loc_dofs; ++i)
 
  315              loc_grad_v.add_outer_product(local_conv_dofs[i], space_data.phi[i].grad);
 
  322              for(
int i(0); i < num_loc_dofs; ++i)
 
  324                streamdiff_coeffs[i] = 
Tiny::dot(loc_v, space_data.phi[i].grad);
 
  330            strain_rate_tensor_2.set_transpose(loc_grad_v);
 
  331            strain_rate_tensor_2.axpy(
DataType(1.0), loc_grad_v);
 
  332            DataType_ gamma_dot = 
Math::sqrt(0.5)*strain_rate_tensor_2.norm_frobenius();
 
  342              for(
int i(0); i < num_loc_dofs; ++i)
 
  345                for(
int j(0); j < num_loc_dofs; ++j)
 
  351                  local_matrix[i][j].add_scalar_main_diag(
value);
 
  361              for(
int i(0); i < num_loc_dofs; ++i)
 
  364                for(
int j(0); j < num_loc_dofs; ++j)
 
  370                  local_matrix[i][j].add_scalar_main_diag(
value);
 
  373                  local_matrix[i][j].add_outer_product(space_data.phi[j].grad, space_data.phi[i].grad, nu_loc * weight);
 
  381              const DataType_ mu_prime = (mu_0 - 
mu_inf) * ((n-DataType_(1.0)) / a) *
 
  384              const DataType fac =  mu_prime / (gamma_dot + reg_eps);
 
  387              for(
int i(0); i < num_loc_dofs; ++i)
 
  389                VectorValue du_grad_phi;
 
  390                du_grad_phi.set_mat_vec_mult(strain_rate_tensor_2, space_data.phi[i].grad);
 
  393                for(
int j(0); j < num_loc_dofs; ++j)
 
  395                  VectorValue du_grad_psi;
 
  396                  du_grad_psi.set_mat_vec_mult(strain_rate_tensor_2, space_data.phi[j].grad);
 
  398                  local_matrix[i][j].add_outer_product(du_grad_phi, du_grad_psi, fac * weight);
 
  410              for(
int i(0); i < num_loc_dofs; ++i)
 
  413                for(
int j(0); j < num_loc_dofs; ++j)
 
  419                  local_matrix[i][j].add_scalar_main_diag(
value);
 
  425            if(need_conv_frechet)
 
  429              for(
int i(0); i < num_loc_dofs; ++i)
 
  432                for(
int j(0); j < num_loc_dofs; ++j)
 
  438                  local_matrix[i][j].axpy(
value, loc_grad_v);
 
  447              for(
int i(0); i < num_loc_dofs; ++i)
 
  450                for(
int j(0); j < num_loc_dofs; ++j)
 
  453                  const DataType value = 
theta * weight *  space_data.phi[i].value * space_data.phi[j].value;
 
  456                  local_matrix[i][j].add_scalar_main_diag(
value);
 
  462            if(need_streamdiff && (local_delta > tol_eps))
 
  465              for(
int i(0); i < num_loc_dofs; ++i)
 
  468                for(
int j(0); j < num_loc_dofs; ++j)
 
  471                  const DataType value = local_delta * weight * streamdiff_coeffs[i] * streamdiff_coeffs[j];
 
  474                  local_matrix[i][j].add_scalar_main_diag(
value);
 
  483          scatter_matrix(local_matrix, dof_mapping, dof_mapping, scale);
 
  486          dof_mapping.finish();
 
  515      template<
typename Space_, 
typename CubatureFactory_>
 
  521        const CubatureFactory_& cubature_factory,
 
  522        const DataType_ scale = DataType_(1)
 
  526        XASSERTM(vector.
size() == space.get_num_dofs(), 
"invalid vector size");
 
  527        XASSERTM(convect.
size() == space.get_num_dofs(), 
"invalid vector size");
 
  542        const typename AsmTraits::TrafoType& trafo = space.get_trafo();
 
  545        typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
 
  548        typename AsmTraits::SpaceEvaluator space_eval(space);
 
  551        typename AsmTraits::DofMapping dof_mapping(space);
 
  554        typename AsmTraits::TrafoEvalData trafo_data;
 
  557        typename AsmTraits::SpaceEvalData space_data;
 
  560        typename AsmTraits::CubatureRuleType cubature_rule(Cubature::ctor_factory, cubature_factory);
 
  563        typename VectorType::ScatterAxpy scatter_vector(vector);
 
  566        typename VectorType::GatherAxpy gather_conv(convect);
 
  569        typename VectorType::GatherAxpy gather_prim(primal);
 
  572        static constexpr int max_local_dofs = AsmTraits::max_local_test_dofs;
 
  577        LocalVectorType local_vector;
 
  580        LocalVectorType local_conv_dofs;
 
  583        LocalVectorType local_prim_dofs;
 
  597        for(
typename AsmTraits::CellIterator cell(trafo_eval.begin()); cell != trafo_eval.end(); ++cell)
 
  600          trafo_eval.prepare(cell);
 
  603          space_eval.prepare(trafo_eval);
 
  606          dof_mapping.prepare(cell);
 
  609          const int num_loc_dofs = space_eval.get_num_local_dofs();
 
  612          local_conv_dofs.format();
 
  613          gather_conv(local_conv_dofs, dof_mapping);
 
  616          local_prim_dofs.format();
 
  617          gather_prim(local_prim_dofs, dof_mapping);
 
  620          local_vector.format();
 
  623          for(
int point(0); point < cubature_rule.get_num_points(); ++point)
 
  626            trafo_eval(trafo_data, cubature_rule.get_point(point));
 
  629            space_eval(space_data, trafo_data);
 
  632            const DataType weight = trafo_data.jac_det * cubature_rule.get_weight(point);
 
  638              for(
int i(0); i < num_loc_dofs; ++i)
 
  641                loc_v.
axpy(space_data.phi[i].value, local_conv_dofs[i]);
 
  644            if(diff || frechet_diff)
 
  648              for(
int i(0); i < num_loc_dofs; ++i)
 
  657            for(
int i(0); i < num_loc_dofs; ++i)
 
  676              for(
int i(0); i < num_loc_dofs; ++i)
 
  679                for(
int j(0); j < num_loc_dofs; ++j)
 
  685                  local_vector[i].axpy(
value, local_prim_dofs[j]);
 
  694              for(
int i(0); i < num_loc_dofs; ++i)
 
  697                for(
int j(0); j < num_loc_dofs; ++j)
 
  700                  const DataType value1 = nu_loc * weight * 
Tiny::dot(space_data.phi[i].grad, space_data.phi[j].grad);
 
  703                  const DataType value2 = nu_loc * weight * 
Tiny::dot(local_prim_dofs[j], space_data.phi[i].grad);
 
  706                  local_vector[i].axpy(value1, local_prim_dofs[j]);
 
  707                  local_vector[i].axpy(value2, space_data.phi[j].grad);
 
  716              for(
int i(0); i < num_loc_dofs; ++i)
 
  719                for(
int j(0); j < num_loc_dofs; ++j)
 
  725                  local_vector[i].axpy(
value, local_prim_dofs[j]);
 
  734              for(
int i(0); i < num_loc_dofs; ++i)
 
  737                for(
int j(0); j < num_loc_dofs; ++j)
 
  740                  const DataType value = 
theta * weight *  space_data.phi[i].value * space_data.phi[j].value;
 
  743                  local_vector[i].axpy(
value, local_prim_dofs[j]);
 
  752          scatter_vector(local_vector, dof_mapping, scale);
 
  755          dof_mapping.finish();
 
  771        const auto* vals = convect.
elements();
 
  787      template<
typename LocalVector_, 
typename Mirror_>
 
  791        const auto* gate = convect.
get_gate();
 
  793          this->sd_v_norm = gate->
max(this->sd_v_norm);
 
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Common single-space assembly traits class template.
Burgers operator assembly class.
DataType_ DataType
the datatype we use here
DataType_ sd_delta
scaling parameter for streamline diffusion stabilization operator S
DataType_ sd_nu
viscosity parameter nu_S for streamline diffusion (usually equal to nu)
DataType_ sd_v_norm
velocity norm for streamline diffusion
void assemble_vector(LAFEM::DenseVectorBlocked< DataType_, IndexType_, dim_ > &vector, const LAFEM::DenseVectorBlocked< DataType_, IndexType_, dim_ > &convect, const LAFEM::DenseVectorBlocked< DataType_, IndexType_, dim_ > &primal, const Space_ &space, const CubatureFactory_ &cubature_factory, const DataType_ scale=DataType_(1)) const
Assembles the Burgers operator into a vector.
BurgersAssemblerCarreau()
default constructor
bool deformation
specifies whether to use the deformation tensor
DataType_ frechet_beta
scaling parameter for Frechet derivative of convective operator K'
DataType_ mu_inf
Carreau Data Parameter.
DataType_ beta
scaling parameter for convective operator K
DataType_ theta
scaling parameter for diffusive operator L (aka viscosity)
void assemble_matrix(LAFEM::SparseMatrixBCSR< DataType_, IndexType_, dim_, dim_ > &matrix, const LAFEM::DenseVectorBlocked< DataType_, IndexType_, dim_ > &convect, const Space_ &space, const CubatureFactory_ &cubature_factory, const DataType_ scale=DataType_(1)) const
Assembles the Burgers operator into a matrix.
void set_sd_v_norm(const LAFEM::DenseVectorBlocked< DataType_, IndexType_, dim_ > &convect)
Sets the convection field norm  for the local streamline diffusion parameter delta_T.
void set_sd_v_norm(const Global::Vector< LocalVector_, Mirror_ > &convect)
Sets the convection field norm  for the streamline diffusion parameter delta_T.
DataType max(DataType x) const
Computes the maximum of a scalar variable over all processes.
Global vector wrapper class template.
const GateType * get_gate() const
Returns a const pointer to the internal gate of the vector.
LocalVector_ & local()
Returns a reference to the internal local LAFEM vector object.
Blocked Dense data vector class template.
auto elements() const -> const typename Intern::DenseVectorBlockedPerspectiveHelper< DT_, BlockSize_, perspective_ >::Type *
Retrieve a pointer to the data array.
Index size() const
The number of elements.
CSR based blocked sparse matrix.
Index rows() const
Retrieve matrix row count.
Index columns() const
Retrieve matrix column count.
Tiny Matrix class template.
CUDA_HOST_DEVICE Matrix & add_outer_product(const Vector< T_, m_, snx_ > &x, const Vector< T_, n_, sny_ > &y, const DataType alpha=DataType(1))
Adds the outer product of two vectors onto the matrix.
CUDA_HOST_DEVICE Matrix & set_transpose(const Matrix< T_, n_, m_, sma_, sna_ > &a)
Sets this matrix to the transpose of another matrix.
CUDA_HOST_DEVICE Matrix & axpy(DataType alpha, const Matrix< T_, m_, n_, sma_, sna_ > &a)
Adds another scaled matrix onto this matrix.
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the matrix.
CUDA_HOST_DEVICE DataType norm_frobenius() const
Returns the Frobenius norm of the matrix.
Tiny Vector class template.
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the vector.
CUDA_HOST_DEVICE Vector & axpy(DataType alpha, const Vector< T_, n_, snx_ > &x)
Adds another scaled vector onto this vector.
T_ sqrt(T_ x)
Returns the square-root of a value.
T_ abs(T_ x)
Returns the absolute value.
T_ pow(T_ x, T_ y)
Returns x raised to the power of y.
T_ max(T_ a, T_ b)
Returns the maximum of two values.
CUDA_HOST_DEVICE T_ dot(const T_ &a, const T_ &b)
Computes the dot-product of two scalars.
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
Reference cell traits structure.