FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
burgers_velo_material_assembly_job.hpp
1
2// FEAT3: Finite Element Analysis Toolbox, Version 3
3// Copyright (C) 2010 - 2023 by Stefan Turek & the FEAT group
4// FEAT3 is released under the GNU General Public License version 3,
5// see the file 'copyright.txt' in the top level directory for details.
6
7#pragma once
8#ifndef KERNEL_ASSEMBLY_BURGERS_VELO_MATERIAL_ASSEMBLY_JOB_HPP
9#define KERNEL_ASSEMBLY_BURGERS_VELO_MATERIAL_ASSEMBLY_JOB_HPP 1
10
11#include <kernel/assembly/base.hpp>
12#include <kernel/assembly/asm_traits.hpp>
13#include <kernel/cubature/dynamic_factory.hpp>
14#include <kernel/lafem/dense_vector.hpp>
15#include <kernel/lafem/sparse_matrix_bcsr.hpp>
16#include <kernel/lafem/dense_vector_blocked.hpp>
17#include <kernel/global/vector.hpp>
18
19namespace FEAT
20{
21 namespace Assembly
22 {
59 template<typename DataType_, typename Space_, typename ViscFunc_, typename ViscDerFunc_, typename ConvVector_>
60 class BurgersVeloMaterialAssemblyJobBase
61 {
62 public:
64 typedef DataType_ DataType;
65
67 typedef Space_ SpaceType;
68
70 typedef ConvVector_ ConvVectorType;
71
73 typedef ViscFunc_ ViscosityFunctionType;
74
76 typedef ViscDerFunc_ ViscosityDerivFunctionType;
77
79 ViscosityFunctionType visco_func;
80
82 ViscosityDerivFunctionType visco_der_func;
83
85 bool deformation;
86
88 DataType_ nu;
89
91 DataType_ theta;
92
94 DataType_ beta;
95
97 DataType_ frechet_beta;
98
100 DataType aT;
101
103 DataType_ sd_delta;
104
106 DataType_ sd_nu;
107
109 DataType_ sd_v_norm;
110
112 DataType_ reg_eps;
113
115 const ConvVector_& convection_vector;
116
118 const Space_& space;
119
121 Cubature::DynamicFactory cubature_factory;
122
124 DataType frechet_material;
125
127 DataType alpha;
128
129 public:
142 explicit BurgersVeloMaterialAssemblyJobBase(const ConvVector_& conv_vector, const Space_& space_, const String& cubature,
143 ViscosityFunctionType _visc_fun, ViscosityDerivFunctionType _visc_der_fun) :
144 visco_func(_visc_fun),
145 visco_der_func(_visc_der_fun),
146 deformation(false),
147 nu(DataType_(0)),
148 theta(DataType_(0)),
149 beta(DataType_(0)),
150 frechet_beta(DataType_(0)),
151 aT(DataType(1)),
152 sd_delta(DataType_(0)),
153 sd_nu(DataType_(0)),
154 sd_v_norm(DataType_(0)),
155 reg_eps(DataType_(1E-100)),
156 convection_vector(conv_vector),
157 space(space_),
158 cubature_factory(cubature),
159 frechet_material(DataType(0)),
160 alpha(DataType(1))
161 {
162 }
163
173 template<typename IndexType_, int conv_dim_>
174 static DataType calc_sd_v_norm(const LAFEM::DenseVectorBlocked<DataType_, IndexType_, conv_dim_>& convect)
175 {
176 const auto* vals = convect.elements();
177 DataType_ r = DataType_(0);
178 for(Index i(0); i < convect.size(); ++i)
179 r = Math::max(r, vals[i].norm_euclid());
180 return r;
181 }
182
195 template<typename LocalVector_, typename Mirror_>
196 static DataType calc_sd_v_norm(const Global::Vector<LocalVector_, Mirror_>& convect)
197 {
198 const auto* gate = convect.get_gate();
199 if(gate != nullptr)
200 return gate->max(calc_sd_v_norm(convect.local()));
201 else
202 return calc_sd_v_norm(convect.local());
203 }
204
211 template<typename VectorType_>
212 void set_sd_v_norm(const VectorType_& convect)
213 {
214 this->sd_v_norm = calc_sd_v_norm(convect);
215 }
216 }; // class BurgersVeloMaterialAssemblyJobBase<...>
217
247 template<typename Job_, typename DataType_, typename Function_>
248 class BurgersVeloMaterialAssemblyTaskBase
249 {
250 public:
252 static constexpr bool need_scatter = true;
254 static constexpr bool need_combine = false;
255
257 typedef DataType_ DataType;
258
260 typedef typename Job_::SpaceType SpaceType;
261
263 typedef typename Job_::ConvVectorType ConvVectorType;
264
266 static constexpr int shape_dim = SpaceType::shape_dim;
267
269 static constexpr int conv_dim = ConvVectorType::BlockSize;
270
272 typedef AsmTraits1<DataType, SpaceType, TrafoTags::jac_det, SpaceTags::value|SpaceTags::grad> AsmTraits;
273
275 typedef Function_ FunctionType;
276
278 const Job_& job;
279
281 const FunctionType visco_func;
282
284 const DataType tol_eps;
285
287 const bool deformation;
288
290 const DataType nu;
291
293 const DataType theta;
294
296 const DataType beta;
297
299 const DataType frechet_beta;
300
302 const DataType sd_delta;
303
305 const DataType sd_nu;
306
308 const DataType sd_v_norm;
309
311 const DataType material_frechet;
312
314 const DataType aT;
315
317 const bool need_diff, need_conv, need_conv_frechet, need_reac, need_streamdiff, need_material_frechet;
318
320 DataType_ gamma_dot, reg_eps, nu_loc;
321
323 bool need_loc_v, need_loc_grad_v, need_mean_v, need_local_h;
324
326 const SpaceType& space;
328 const typename AsmTraits::TrafoType& trafo;
330 typename AsmTraits::TrafoEvaluator trafo_eval;
332 typename AsmTraits::SpaceEvaluator space_eval;
334 typename AsmTraits::DofMapping dof_mapping;
336 typename AsmTraits::CubatureRuleType cubature_rule;
338 typename AsmTraits::TrafoEvalData trafo_data;
340 typename AsmTraits::SpaceEvalData space_data;
342 typename ConvVectorType::GatherAxpy gather_conv;
343
345 static constexpr int max_local_dofs = AsmTraits::max_local_test_dofs;
346
348 int num_local_dofs;
349
351 Tiny::Vector<Tiny::Vector<DataType, conv_dim>, max_local_dofs> local_conv_dofs;
352
354 Tiny::Vector<DataType, conv_dim> loc_v, mean_v;
355
357 Tiny::Matrix<DataType, conv_dim, conv_dim> loc_grad_v;
358
360 Tiny::Matrix<DataType, conv_dim, conv_dim> strain_rate_tensor_2;
361
363 Tiny::Vector<DataType, max_local_dofs> streamdiff_coeffs;
364
366 Tiny::Vector<DataType, shape_dim> barycenter;
367
369 DataType local_h;
370
372 DataType local_delta;
373
375 DataType alpha = DataType(1);
376
377 public:
384 explicit BurgersVeloMaterialAssemblyTaskBase(const Job_& job_) :
385 job(job_),
386 visco_func(job_.visco_func),
387 tol_eps(Math::sqrt(Math::eps<DataType>())),
388 deformation(job_.deformation),
389 nu(job_.nu),
390 theta(job_.theta),
391 beta(job_.beta),
392 frechet_beta(job_.frechet_beta),
393 sd_delta(job_.sd_delta),
394 sd_nu(job_.sd_nu),
395 sd_v_norm(job_.sd_v_norm),
396 material_frechet(job_.frechet_material),
397 aT(job_.aT),
398 need_diff(true),
399 need_conv(Math::abs(beta) > DataType(0)),
400 need_conv_frechet(Math::abs(frechet_beta) > DataType(0)),
401 need_reac(Math::abs(theta) > DataType(0)),
402 need_streamdiff((Math::abs(sd_delta) > DataType(0)) && (sd_v_norm > tol_eps)),
403 need_material_frechet(material_frechet > DataType(0)),
404 gamma_dot(),
405 reg_eps(job_.reg_eps),
406 nu_loc(nu),
407 need_loc_v(need_conv),
408 need_loc_grad_v(true),
409 need_mean_v(need_streamdiff),
410 need_local_h(need_streamdiff),
411 space(job_.space),
412 trafo(space.get_trafo()),
413 trafo_eval(trafo),
414 space_eval(space),
415 dof_mapping(space),
416 cubature_rule(Cubature::ctor_factory, job_.cubature_factory),
417 trafo_data(),
418 space_data(),
419 gather_conv(job_.convection_vector),
420 num_local_dofs(0),
421 local_conv_dofs(),
422 loc_v(),
423 mean_v(),
424 loc_grad_v(),
425 strain_rate_tensor_2(),
426 streamdiff_coeffs(),
427 barycenter(),
428 local_h(DataType(0)),
429 local_delta(DataType(0)),
430 alpha(job.alpha)
431 {
432 // compute reference element barycenter
433 for(int i(0); i < shape_dim; ++i)
434 barycenter[i] = Shape::ReferenceCell<typename SpaceType::ShapeType>::template centre<DataType>(i);
435 }
436
443 void prepare(const Index cell)
444 {
445 // prepare dof mapping
446 dof_mapping.prepare(cell);
447
448 // prepare trafo evaluator
449 trafo_eval.prepare(cell);
450
451 // prepare space evaluator
452 space_eval.prepare(trafo_eval);
453
454 // fetch number of local dofs
455 num_local_dofs = space_eval.get_num_local_dofs();
456
457 // gather our local convection dofs
458 local_conv_dofs.format();
459 gather_conv(local_conv_dofs, dof_mapping);
460
461 // compute mesh width if necessary
462 if(need_mean_v || need_local_h || need_streamdiff)
463 {
464 // reset local h and delta
465 local_h = local_delta = DataType(0);
466
467 // evaluate trafo and space at barycenter
468 trafo_eval(trafo_data, barycenter);
469 space_eval(space_data, trafo_data);
470
471 // compute velocity at barycenter
472 mean_v.format();
473 for(int i(0); i < num_local_dofs; ++i)
474 mean_v.axpy(space_data.phi[i].value, local_conv_dofs[i]);
475
476 // compute norm of mean velocity
477 const DataType local_norm_v = mean_v.norm_euclid();
478
479 // do we have a non-zero velocity?
480 if(local_norm_v > tol_eps)
481 {
482 // compute local mesh width w.r.t. mean velocity
483 local_h = trafo_eval.width_directed(mean_v) * local_norm_v;
484
485 // compute local Re_T
486 const DataType local_re = (local_norm_v * local_h) / this->sd_nu;
487
488 // compute local delta
489 local_delta = this->sd_delta * (local_h / this->sd_v_norm) * (DataType(2)*local_re) / (DataType(1) + local_re);
490 }
491 }
492 }
493
504 void prepare_point(int cubature_point)
505 {
506 // compute trafo data
507 trafo_eval(trafo_data, cubature_rule.get_point(cubature_point));
508
509 // compute basis function data
510 space_eval(space_data, trafo_data);
511
512 // evaluate convection function and its gradient (if required)
513 if(need_loc_v || need_conv || need_streamdiff)
514 {
515 loc_v.format();
516 for(int i(0); i < num_local_dofs; ++i)
517 {
518 // update velocity value
519 loc_v.axpy(space_data.phi[i].value, local_conv_dofs[i]);
520 }
521 }
522 if(need_loc_grad_v || need_conv_frechet)
523 {
524 loc_grad_v.format();
525 for(int i(0); i < num_local_dofs; ++i)
526 {
527 // update velocity gradient
528 loc_grad_v.add_outer_product(local_conv_dofs[i], space_data.phi[i].grad);
529 }
530 }
531
532 // evaluate streamline diffusion coefficients
533 if(need_streamdiff)
534 {
535 for(int i(0); i < num_local_dofs; ++i)
536 {
537 streamdiff_coeffs[i] = Tiny::dot(loc_v, space_data.phi[i].grad);
538 }
539 }
540
541 //default to 1, only assemble if carreau is needed...
542 strain_rate_tensor_2.set_transpose(loc_grad_v);
543 strain_rate_tensor_2.axpy(DataType(1.0), loc_grad_v);
544 gamma_dot = Math::sqrt(DataType(0.5))*strain_rate_tensor_2.norm_frobenius();
545
546 //default to nu
547 nu_loc = visco_func(gamma_dot, aT);
548 }
549
553 void finish()
554 {
555 // finish evaluators
556 space_eval.finish();
557 trafo_eval.finish();
558
559 // finish dof mapping
560 dof_mapping.finish();
561 }
562
566 void combine()
567 {
568 // nothing to do here
569 }
570 }; // class BurgersVeloMaterialAssemblyTaskBase<...>
571
591 template<typename Job_, typename DataType_, int block_size_, typename ViscFun_, typename ViscDerFun_>
592 class BurgersVeloMaterialBlockedAssemblyTaskBase :
593 public BurgersVeloMaterialAssemblyTaskBase<Job_, DataType_, ViscFun_>
594 {
595 public:
596 typedef BurgersVeloMaterialAssemblyTaskBase<Job_, DataType_, ViscFun_> BaseClass;
597
598 typedef DataType_ DataType;
599 typedef ViscDerFun_ ViscosityDerivFunctionType;
600
601 using BaseClass::max_local_dofs;
602 using BaseClass::num_local_dofs;
603
604 protected:
606 typedef Tiny::Matrix<DataType_, block_size_, block_size_> MatrixValue;
607 typedef Tiny::Matrix<MatrixValue, max_local_dofs, max_local_dofs> LocalMatrixType;
608 LocalMatrixType local_matrix;
610 ViscosityDerivFunctionType visco_der_func;
611
612 public:
619 explicit BurgersVeloMaterialBlockedAssemblyTaskBase(const Job_& job_) :
620 BaseClass(job_),
621 local_matrix(),
622 visco_der_func(job_.visco_der_func)
623 {
624 }
625
632 void assemble_burgers_point(const DataType weight)
633 {
634 // assemble diffusion matrix?
635 if(this->need_diff)
636 {
637 // assemble gradient-tensor diffusion
638
639 // test function loop
640 for(int i(0); i < this->num_local_dofs; ++i)
641 {
642 // trial function loop
643 for(int j(0); j < this->num_local_dofs; ++j)
644 {
645 // compute scalar value
646 const DataType value = this->nu_loc * weight * Tiny::dot(this->space_data.phi[i].grad, this->space_data.phi[j].grad);
647
648 // update local matrix
649 local_matrix[i][j].add_scalar_main_diag(value);
650 }
651 }
652 // assemble deformation tensor?
653 if(this->deformation)
654 {
655 // test function loop
656 for(int i(0); i < this->num_local_dofs; ++i)
657 {
658 // trial function loop
659 for(int j(0); j < this->num_local_dofs; ++j)
660 {
661 // add outer product of grad(phi) and grad(psi)
662 local_matrix[i][j].add_outer_product(this->space_data.phi[j].grad, this->space_data.phi[i].grad, this->nu_loc * weight);
663 }
664 }
665 // frechet carreau term "only" makes sense in defo formulation
666 if(this->need_material_frechet)
667 {
668 const DataType fac = this->material_frechet * visco_der_func(this->gamma_dot, this->aT)/(this->gamma_dot + this->reg_eps);
669 //std::cout << fac ;
670 // test function loop
671 for(int i(0); i < this->num_local_dofs; ++i)
672 {
673 Tiny::Vector<DataType, BaseClass::ConvVectorType::BlockSize> du_grad_phi;
674 du_grad_phi.set_mat_vec_mult(this->strain_rate_tensor_2, this->space_data.phi[i].grad);
675
676 // trial function loop
677 for(int j(0); j < this->num_local_dofs; ++j)
678 {
679 Tiny::Vector<DataType, BaseClass::ConvVectorType::BlockSize> du_grad_psi;
680 du_grad_psi.set_mat_vec_mult(this->strain_rate_tensor_2, this->space_data.phi[j].grad);
681 // add outer product of grad(phi) and grad(psi)
682 local_matrix[i][j].add_outer_product(du_grad_phi, du_grad_psi, fac * weight);
683 }
684 }
685 }
686 }
687 }
688
689 // assemble convection?
690 if(this->need_conv)
691 {
692 // test function loop
693 for(int i(0); i < this->num_local_dofs; ++i)
694 {
695 // trial function loop
696 for(int j(0); j < this->num_local_dofs; ++j)
697 {
698 // compute scalar value
699 const DataType value = this->beta * weight * this->space_data.phi[i].value * Tiny::dot(this->loc_v, this->space_data.phi[j].grad);
700
701 // update local matrix
702 local_matrix[i][j].add_scalar_main_diag(value);
703 }
704 }
705 }
706
707 // assemble convection Frechet?
708 if(this->need_conv_frechet)
709 {
710 // test function loop
711 for(int i(0); i < this->num_local_dofs; ++i)
712 {
713 // trial function loop
714 for(int j(0); j < this->num_local_dofs; ++j)
715 {
716 // compute scalar value
717 const DataType value = this->frechet_beta * weight * this->space_data.phi[i].value * this->space_data.phi[j].value;
718
719 // update local matrix
720 local_matrix[i][j].axpy(value, this->loc_grad_v);
721 }
722 }
723 }
724
725 // assemble reaction?
726 if(this->need_reac)
727 {
728 // test function loop
729 for(int i(0); i < this->num_local_dofs; ++i)
730 {
731 // trial function loop
732 for(int j(0); j < this->num_local_dofs; ++j)
733 {
734 // compute scalar value
735 const DataType value = this->theta * weight * this->space_data.phi[i].value * this->space_data.phi[j].value;
736
737 // update local matrix
738 local_matrix[i][j].add_scalar_main_diag(value);
739 }
740 }
741 }
742 }
743
750 void assemble_streamline_diffusion(const DataType weight)
751 {
752 // assemble streamline diffusion?
753 if(this->need_streamdiff && (this->local_delta > this->tol_eps))
754 {
755 // test function loop
756 for(int i(0); i < this->num_local_dofs; ++i)
757 {
758 // trial function loop
759 for(int j(0); j < this->num_local_dofs; ++j)
760 {
761 // compute scalar value
762 const DataType value = this->local_delta * weight * this->streamdiff_coeffs[i] * this->streamdiff_coeffs[j];
763
764 // update local matrix
765 local_matrix[i][j].add_scalar_main_diag(value);
766 }
767 }
768 }
769 }
770
774 void assemble()
775 {
776 local_matrix.format();
777
778 // loop over all quadrature points and integrate
779 for(int point(0); point < this->cubature_rule.get_num_points(); ++point)
780 {
781 // prepare trafo and space for cubature point
782 this->prepare_point(point);
783
784 // precompute cubature weight
785 const DataType weight = this->trafo_data.jac_det * this->cubature_rule.get_weight(point);
786
787 // assemble the Burgers operator
788 this->assemble_burgers_point(weight);
789
790 // assemble the streamline diffusion
791 this->assemble_streamline_diffusion(weight);
792 } // continue with next cubature point
793 }
794 }; // class BurgersVeloMaterialBlockedAssemblyTaskBase<...>
795
820 template<typename Matrix_, typename Space_, typename ViscoFunc_, typename ViscoDerFunc_, typename ConvVector_ = typename Matrix_::VectorTypeR>
821 class BurgersVeloMaterialBlockedMatrixAssemblyJob :
822 public BurgersVeloMaterialAssemblyJobBase<typename Matrix_::DataType, Space_, ViscoFunc_, ViscoDerFunc_, ConvVector_>
823 {
824 public:
826 typedef Matrix_ MatrixType;
828 typedef typename MatrixType::DataType DataType;
829
831 typedef BurgersVeloMaterialAssemblyJobBase<DataType, Space_, ViscoFunc_, ViscoDerFunc_, ConvVector_> BaseClass;
832
833 // no nonsense, please
834 static_assert(Matrix_::BlockHeight == Matrix_::BlockWidth, "only square matrix blocks are supported here");
835
837 static constexpr int block_size = Matrix_::BlockHeight;
838
840 MatrixType& matrix;
841
842 public:
858 explicit BurgersVeloMaterialBlockedMatrixAssemblyJob(Matrix_& matrix_, const ConvVector_& conv_vector,
859 const Space_& space_, const String& cubature_name, ViscoFunc_ visc_fun, ViscoDerFunc_ visc_der_func) :
860 BaseClass(conv_vector, space_, cubature_name, visc_fun, visc_der_func),
861 matrix(matrix_)
862 {
863 }
864
865 public:
867 class Task :
868 public BurgersVeloMaterialBlockedAssemblyTaskBase<BurgersVeloMaterialBlockedMatrixAssemblyJob, DataType, block_size, ViscoFunc_, ViscoDerFunc_>
869 {
870 public:
871 typedef BurgersVeloMaterialBlockedAssemblyTaskBase<BurgersVeloMaterialBlockedMatrixAssemblyJob, DataType, block_size, ViscoFunc_, ViscoDerFunc_> BaseClass;
872
873 protected:
875 typename MatrixType::ScatterAxpy scatter_matrix;
876
877 public:
879 explicit Task(const BurgersVeloMaterialBlockedMatrixAssemblyJob& job_) :
880 BaseClass(job_),
881 scatter_matrix(job_.matrix)
882 {
883 }
884
885 // prepare, assemble and finish are already implemented in the base classes
886
888 void scatter()
889 {
890 this->scatter_matrix(this->local_matrix, this->dof_mapping, this->dof_mapping, this->alpha);
891 }
892 }; // class BurgersVeloMaterialBlockedMatrixAssemblyJob::Task
893 }; // class BurgersVeloMaterialBlockedMatrixAssemblyJob
894
919 template<typename DiagonalVector_, typename Space_, typename ViscoFunc_, typename ViscoDerFunc_, typename ConvVector_ = DiagonalVector_>
920 class BurgersVeloMaterialBlockedDiagonalAssemblyJob :
921 public BurgersVeloMaterialAssemblyJobBase<typename DiagonalVector_::DataType, Space_, ViscoFunc_, ViscoDerFunc_, ConvVector_>
922 {
923 public:
925 typedef DiagonalVector_ VectorType;
927 typedef typename VectorType::DataType DataType;
928
930 typedef BurgersVeloMaterialAssemblyJobBase<DataType, Space_, ViscoFunc_, ViscoDerFunc_, ConvVector_> BaseClass;
931
933 static constexpr int block_size = VectorType::BlockSize;
934
936 VectorType& vector;
937
938 public:
954 explicit BurgersVeloMaterialBlockedDiagonalAssemblyJob(DiagonalVector_& vector_, const ConvVector_& conv_vector,
955 const Space_& space_, const String& cubature_name, ViscoFunc_ visc_fun, ViscoDerFunc_ visc_der_func) :
956 BaseClass(conv_vector, space_, cubature_name, visc_fun, visc_der_func),
957 vector(vector_)
958 {
959 }
960
961 public:
963 class Task :
964 public BurgersVeloMaterialBlockedAssemblyTaskBase<BurgersVeloMaterialBlockedDiagonalAssemblyJob, DataType, block_size, ViscoFunc_, ViscoDerFunc_>
965 {
966 public:
967 typedef BurgersVeloMaterialBlockedAssemblyTaskBase<BurgersVeloMaterialBlockedDiagonalAssemblyJob, DataType, block_size, ViscoFunc_, ViscoDerFunc_> BaseClass;
968
969 protected:
970 DiagonalVector_& vector;
971
972 public:
974 explicit Task(const BurgersVeloMaterialBlockedDiagonalAssemblyJob& job_) :
975 BaseClass(job_),
976 vector(job_.vector)
977 {
978 }
979
980 // prepare, assemble and finish are already implemented in the base classes
981
983 void scatter()
984 {
985 auto* val_vec = vector.elements();
986 for(int loc_i = 0; loc_i < this->dof_mapping.get_num_local_dofs(); ++loc_i)
987 {
988 const Index cur_i = this->dof_mapping.get_index(loc_i);
989 for(int k = 0; k < block_size; ++k)
990 val_vec[cur_i][k] += this->local_matrix[loc_i][loc_i][k][k] * this->alpha;
991 }
992 }
993 }; // class BurgersVeloMaterialBlockedMatrixAssemblyJob::Task
994 }; // class BurgersVeloMaterialBlockedMatrixAssemblyJob
995
1016 template<typename Vector_, typename Space_, typename ViscFunc_, typename ViscDerFunc_, typename ConvVector_ = Vector_>
1017 class BurgersVeloMaterialBlockedVectorAssemblyJob :
1018 public BurgersVeloMaterialAssemblyJobBase<typename Vector_::DataType, Space_, ViscFunc_, ViscDerFunc_, ConvVector_>
1019 {
1020 public:
1022 typedef Vector_ VectorType;
1024 typedef typename VectorType::DataType DataType;
1025
1027 typedef BurgersVeloMaterialAssemblyJobBase<DataType, Space_, ViscFunc_, ViscDerFunc_, ConvVector_> BaseClass;
1028
1030 static constexpr int block_size = Vector_::BlockSize;
1031
1033 VectorType& vector_rhs;
1034
1036 const VectorType& vector_sol;
1037
1038 public:
1059 explicit BurgersVeloMaterialBlockedVectorAssemblyJob(Vector_& rhs_vector_, const Vector_& sol_vector_,
1060 const ConvVector_& conv_vector, const Space_& space_, const String& cubature_name,
1061 ViscFunc_ visc_fun, ViscDerFunc_ visc_der_func) :
1062 BaseClass(conv_vector, space_, cubature_name, visc_fun, visc_der_func),
1063 vector_rhs(rhs_vector_),
1064 vector_sol(sol_vector_)
1065 {
1066 XASSERTM(&rhs_vector_ != &sol_vector_, "rhs and solution vectors must not be the same object");
1067 // compare void addresses to avoid warnings in case the classes are different
1068 XASSERTM((void*)&rhs_vector_ != (void*)&conv_vector, "rhs and convection vectors must not be the same object");
1069 }
1070
1071 public:
1073 class Task :
1074 public BurgersVeloMaterialBlockedAssemblyTaskBase<BurgersVeloMaterialBlockedVectorAssemblyJob, DataType, block_size, ViscFunc_, ViscDerFunc_>
1075 {
1076 public:
1077 typedef BurgersVeloMaterialBlockedAssemblyTaskBase<BurgersVeloMaterialBlockedVectorAssemblyJob, DataType, block_size, ViscFunc_, ViscDerFunc_> BaseClass;
1078
1079 using BaseClass::max_local_dofs;
1080
1081 protected:
1083 typename VectorType::GatherAxpy gather_vec_sol;
1085 typename VectorType::ScatterAxpy scatter_vec_rhs;
1087 const bool sol_equals_conv;
1088
1090 Tiny::Vector<Tiny::Vector<DataType, block_size>, max_local_dofs> local_sol_dofs;
1091
1093 Tiny::Vector<Tiny::Vector<DataType, block_size>, max_local_dofs> local_vector;
1094
1095 public:
1097 explicit Task(const BurgersVeloMaterialBlockedVectorAssemblyJob& job_) :
1098 BaseClass(job_),
1099 gather_vec_sol(job_.vector_sol),
1100 scatter_vec_rhs(job_.vector_rhs),
1101 sol_equals_conv((void*)&job_.vector_sol == (void*)&job_.convection_vector),
1102 local_sol_dofs(),
1103 local_vector()
1104 {
1105 }
1106
1107 void prepare(const Index cell)
1108 {
1109 BaseClass::prepare(cell);
1110
1111 // gather local solution dofs if required
1112 if(!sol_equals_conv)
1113 {
1114 this->local_sol_dofs.format();
1115 this->gather_vec_sol(this->local_sol_dofs, this->dof_mapping);
1116 }
1117 }
1118
1122 void compute_local_vector()
1123 {
1124 local_vector.format();
1125
1126 // compute local vector from local matrix and sol vector dofs
1127 if(!sol_equals_conv)
1128 {
1129 for(int i(0); i < this->num_local_dofs; ++i)
1130 for(int j(0); j < this->num_local_dofs; ++j)
1131 this->local_vector[i].add_mat_vec_mult(this->local_matrix(i,j), this->local_sol_dofs[j]);
1132 }
1133 else
1134 {
1135 for(int i(0); i < this->num_local_dofs; ++i)
1136 for(int j(0); j < this->num_local_dofs; ++j)
1137 this->local_vector[i].add_mat_vec_mult(this->local_matrix(i,j), this->local_conv_dofs[j]);
1138 }
1139 }
1140
1141 void assemble()
1142 {
1143 // assemble the local matrix
1144 BaseClass::assemble();
1145
1146 // compute the local vector from the matrix
1147 compute_local_vector();
1148 }
1149
1151 void scatter()
1152 {
1153 this->scatter_vec_rhs(this->local_vector, this->dof_mapping, this->alpha);
1154 }
1155 }; // class BurgersVeloMaterialBlockedVectorAssemblyJob::Task
1156 }; // class BurgersVeloMaterialBlockedVectorAssemblyJob<...>
1157
1176 template<typename Job_, typename DataType_, typename ViscFunc_, typename ViscDerFunc_>
1177 class BurgersVeloMaterialScalarAssemblyTaskBase :
1178 public BurgersVeloMaterialAssemblyTaskBase<Job_, DataType_, ViscFunc_>
1179 {
1180 public:
1181 typedef BurgersVeloMaterialAssemblyTaskBase<Job_, DataType_, ViscFunc_> BaseClass;
1182
1183 typedef DataType_ DataType;
1184
1185 using BaseClass::max_local_dofs;
1186 using BaseClass::num_local_dofs;
1187
1188 protected:
1190 typedef Tiny::Matrix<DataType, max_local_dofs, max_local_dofs> LocalMatrixType;
1191 LocalMatrixType local_matrix;
1192 ViscDerFunc_ visco_der_fun;
1193
1194 public:
1201 explicit BurgersVeloMaterialScalarAssemblyTaskBase(const Job_& job_) :
1202 BaseClass(job_),
1203 local_matrix(),
1204 visco_der_fun(job_.visc_der_fun)
1205 {
1206 }
1207
1214 void assemble_burgers_point(const DataType weight)
1215 {
1216 // assemble diffusion matrix?
1217 if(this->need_diff)
1218 {
1219 // assemble gradient-tensor diffusion
1220
1221 // test function loop
1222 for(int i(0); i < this->num_local_dofs; ++i)
1223 {
1224 // trial function loop
1225 for(int j(0); j < this->num_local_dofs; ++j)
1226 {
1227 local_matrix[i][j] += this->nu_loc * weight
1228 * Tiny::dot(this->space_data.phi[i].grad, this->space_data.phi[j].grad);
1229 }
1230 }
1231
1232 // \TODO: additional frechet term?
1233 }
1234
1235 // assemble convection?
1236 if(this->need_conv)
1237 {
1238 // test function loop
1239 for(int i(0); i < this->num_local_dofs; ++i)
1240 {
1241 // trial function loop
1242 for(int j(0); j < this->num_local_dofs; ++j)
1243 {
1244 local_matrix[i][j] += this->beta * weight
1245 * this->space_data.phi[i].value * Tiny::dot(this->loc_v, this->space_data.phi[j].grad);
1246 }
1247 }
1248 }
1249
1250 // assemble reaction?
1251 if(this->need_reac)
1252 {
1253 // test function loop
1254 for(int i(0); i < this->num_local_dofs; ++i)
1255 {
1256 // trial function loop
1257 for(int j(0); j < this->num_local_dofs; ++j)
1258 {
1259 local_matrix[i][j] += this->theta * weight
1260 * this->space_data.phi[i].value * this->space_data.phi[j].value;
1261 }
1262 }
1263 }
1264 }
1265
1272 void assemble_streamline_diffusion(const DataType weight)
1273 {
1274 // assemble streamline diffusion?
1275 if(this->need_streamdiff && (this->local_delta > this->tol_eps))
1276 {
1277 // test function loop
1278 for(int i(0); i < this->num_local_dofs; ++i)
1279 {
1280 // trial function loop
1281 for(int j(0); j < this->num_local_dofs; ++j)
1282 {
1283 local_matrix[i][j] += this->local_delta * weight
1284 * this->streamdiff_coeffs[i] * this->streamdiff_coeffs[j];
1285 }
1286 }
1287 }
1288 }
1289
1293 void assemble()
1294 {
1295 local_matrix.format();
1296
1297 // loop over all quadrature points and integrate
1298 for(int point(0); point < this->cubature_rule.get_num_points(); ++point)
1299 {
1300 // prepare trafo and space for cubature point
1301 this->prepare_point(point);
1302
1303 // precompute cubature weight
1304 const DataType weight = this->trafo_data.jac_det * this->cubature_rule.get_weight(point);
1305
1306 // assemble the Burgers operator
1307 this->assemble_burgers_point(weight);
1308
1309 // assembles the streamline diffusion stabilization
1310 this->assemble_streamline_diffusion(weight);
1311 } // continue with next cubature point
1312 }
1313 }; // class BurgersVeloMaterialScalarAssemblyTaskBase<...>
1314
1335 template<typename Matrix_, typename Space_, typename ViscFunc_, typename ViscDerFunc_, typename ConvVector_>
1336 class BurgersVeloMaterialScalarMatrixAssemblyJob :
1337 public BurgersVeloMaterialAssemblyJobBase<typename Matrix_::DataType, Space_, ViscFunc_, ViscDerFunc_, ConvVector_>
1338 {
1339 public:
1341 typedef Matrix_ MatrixType;
1343 typedef typename MatrixType::DataType DataType;
1344
1346 typedef BurgersVeloMaterialAssemblyJobBase<DataType, Space_, ViscFunc_, ViscDerFunc_, ConvVector_> BaseClass;
1347
1349 MatrixType& matrix;
1350
1351 public:
1367 explicit BurgersVeloMaterialScalarMatrixAssemblyJob(Matrix_& matrix_, const ConvVector_& conv_vector,
1368 const Space_& space_, const String& cubature_name,
1369 ViscFunc_ visc_fun, ViscDerFunc_ visc_der_fun) :
1370 BaseClass(conv_vector, space_, cubature_name, visc_fun, visc_der_fun),
1371 matrix(matrix_)
1372 {
1373 }
1374
1375 public:
1377 class Task :
1378 public BurgersVeloMaterialScalarAssemblyTaskBase<BurgersVeloMaterialScalarMatrixAssemblyJob, DataType, ViscFunc_, ViscDerFunc_>
1379 {
1380 public:
1381 typedef BurgersVeloMaterialScalarAssemblyTaskBase<BurgersVeloMaterialScalarMatrixAssemblyJob, DataType, ViscFunc_, ViscDerFunc_> BaseClass;
1382
1383 protected:
1385 typename MatrixType::ScatterAxpy scatter_matrix;
1386
1387 public:
1389 explicit Task(const BurgersVeloMaterialScalarMatrixAssemblyJob& job_) :
1390 BaseClass(job_),
1391 scatter_matrix(job_.matrix)
1392 {
1393 }
1394
1395 // prepare, assemble and finish are already implemented in the base classes
1396
1398 void scatter()
1399 {
1400 this->scatter_matrix(this->local_matrix, this->dof_mapping, this->dof_mapping, this->alpha);
1401 }
1402 }; // class BurgersVeloMaterialScalarMatrixAssemblyJob::Task
1403 }; // class BurgersVeloMaterialScalarMatrixAssemblyJob
1404
1425 template<typename Vector_, typename Space_, typename ViscoFunc_, typename ViscoDerFunc_, typename ConvVector_>
1426 class BurgersVeloMaterialScalarVectorAssemblyJob :
1427 public BurgersVeloMaterialAssemblyJobBase<typename Vector_::DataType, Space_, ViscoFunc_, ViscoDerFunc_, ConvVector_>
1428 {
1429 public:
1431 typedef Vector_ VectorType;
1433 typedef typename VectorType::DataType DataType;
1434
1436 typedef BurgersVeloMaterialAssemblyJobBase<DataType, Space_, ViscoFunc_, ViscoDerFunc_, ConvVector_> BaseClass;
1437
1439 VectorType& vector_rhs;
1440
1442 const VectorType& vector_sol;
1443
1444 public:
1465 explicit BurgersVeloMaterialScalarVectorAssemblyJob(Vector_& rhs_vector_, const Vector_& sol_vector_,
1466 const ConvVector_& conv_vector, const Space_& space_, const String& cubature_name) :
1467 BaseClass(conv_vector, space_, cubature_name),
1468 vector_rhs(rhs_vector_),
1469 vector_sol(sol_vector_)
1470 {
1471 XASSERTM(&rhs_vector_ != &sol_vector_, "rhs and solution vectors must not be the same object");
1472 }
1473
1474 public:
1476 class Task :
1477 public BurgersVeloMaterialScalarAssemblyTaskBase<BurgersVeloMaterialScalarVectorAssemblyJob, DataType, ViscoFunc_, ViscoDerFunc_>
1478 {
1479 public:
1480 typedef BurgersVeloMaterialScalarAssemblyTaskBase<BurgersVeloMaterialScalarVectorAssemblyJob, DataType, ViscoFunc_, ViscoDerFunc_> BaseClass;
1481
1482 using BaseClass::max_local_dofs;
1483
1484 protected:
1486 typename VectorType::GatherAxpy gather_vec_sol;
1488 typename VectorType::ScatterAxpy scatter_vec_rhs;
1489
1491 Tiny::Vector<DataType, max_local_dofs> local_sol_dofs;
1492
1494 Tiny::Vector<DataType, max_local_dofs> local_vector;
1495
1496 public:
1498 explicit Task(const BurgersVeloMaterialScalarVectorAssemblyJob& job_) :
1499 BaseClass(job_),
1500 gather_vec_sol(job_.vector_sol),
1501 scatter_vec_rhs(job_.vector_rhs),
1502 local_sol_dofs(),
1503 local_vector()
1504 {
1505 }
1506
1507 void prepare(const Index cell)
1508 {
1509 BaseClass::prepare(cell);
1510
1511 // gather local solution vector dofs
1512 this->local_sol_dofs.format();
1513 this->gather_vec_sol(this->local_sol_dofs, this->dof_mapping);
1514 }
1515
1519 void compute_local_vector()
1520 {
1521 // compute local vector from local matrix and sol vector dofs
1522 this->local_vector.format();
1523 for(int i(0); i < this->num_local_dofs; ++i)
1524 for(int j(0); j < this->num_local_dofs; ++j)
1525 this->local_vector[i] += this->local_matrix(i,j) * this->local_sol_dofs[j];
1526 //this->local_vector.set_mat_vec_mult(this->local_matrix, this->local_sol_dofs);
1527 }
1528
1529 void assemble()
1530 {
1531 // assemble the local matrix
1532 BaseClass::assemble();
1533
1534 // compute local vector from the matrix
1535 compute_local_vector();
1536 }
1537
1539 void scatter()
1540 {
1541 this->scatter_vec_rhs(this->local_vector, this->dof_mapping, this->alpha);
1542 }
1543 }; // class BurgersVeloMaterialScalarVectorAssemblyJob::Task
1544 }; // class BurgersVeloMaterialScalarVectorAssemblyJob<...>
1545 } // namespace Assembly
1546} // namespace FEAT
1547
1548#endif // KERNEL_ASSEMBLY_BURGERS_VELO_MATERIAL_ASSEMBLY_JOB_HPP
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
T_ sqrt(T_ x)
Returns the square-root of a value.
Definition: math.hpp:300
T_ abs(T_ x)
Returns the absolute value.
Definition: math.hpp:275
T_ eps()
Returns the machine precision constant for a floating-point data type.
Definition: math.hpp:787
FEAT namespace.
Definition: adjactor.hpp:12
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.