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.