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
915 template<typename Vector_, typename Space_, typename ViscFunc_, typename ViscDerFunc_, typename ConvVector_ = Vector_>
916 class BurgersVeloMaterialBlockedVectorAssemblyJob :
917 public BurgersVeloMaterialAssemblyJobBase<typename Vector_::DataType, Space_, ViscFunc_, ViscDerFunc_, ConvVector_>
918 {
919 public:
921 typedef Vector_ VectorType;
923 typedef typename VectorType::DataType DataType;
924
926 typedef BurgersVeloMaterialAssemblyJobBase<DataType, Space_, ViscFunc_, ViscDerFunc_, ConvVector_> BaseClass;
927
929 static constexpr int block_size = Vector_::BlockSize;
930
932 VectorType& vector_rhs;
933
935 const VectorType& vector_sol;
936
937 public:
958 explicit BurgersVeloMaterialBlockedVectorAssemblyJob(Vector_& rhs_vector_, const Vector_& sol_vector_,
959 const ConvVector_& conv_vector, const Space_& space_, const String& cubature_name,
960 ViscFunc_ visc_fun, ViscDerFunc_ visc_der_func) :
961 BaseClass(conv_vector, space_, cubature_name, visc_fun, visc_der_func),
962 vector_rhs(rhs_vector_),
963 vector_sol(sol_vector_)
964 {
965 XASSERTM(&rhs_vector_ != &sol_vector_, "rhs and solution vectors must not be the same object");
966 // compare void addresses to avoid warnings in case the classes are different
967 XASSERTM((void*)&rhs_vector_ != (void*)&conv_vector, "rhs and convection vectors must not be the same object");
968 }
969
970 public:
972 class Task :
973 public BurgersVeloMaterialBlockedAssemblyTaskBase<BurgersVeloMaterialBlockedVectorAssemblyJob, DataType, block_size, ViscFunc_, ViscDerFunc_>
974 {
975 public:
976 typedef BurgersVeloMaterialBlockedAssemblyTaskBase<BurgersVeloMaterialBlockedVectorAssemblyJob, DataType, block_size, ViscFunc_, ViscDerFunc_> BaseClass;
977
978 using BaseClass::max_local_dofs;
979
980 protected:
982 typename VectorType::GatherAxpy gather_vec_sol;
984 typename VectorType::ScatterAxpy scatter_vec_rhs;
986 const bool sol_equals_conv;
987
989 Tiny::Vector<Tiny::Vector<DataType, block_size>, max_local_dofs> local_sol_dofs;
990
992 Tiny::Vector<Tiny::Vector<DataType, block_size>, max_local_dofs> local_vector;
993
994 public:
996 explicit Task(const BurgersVeloMaterialBlockedVectorAssemblyJob& job_) :
997 BaseClass(job_),
998 gather_vec_sol(job_.vector_sol),
999 scatter_vec_rhs(job_.vector_rhs),
1000 sol_equals_conv((void*)&job_.vector_sol == (void*)&job_.convection_vector),
1001 local_sol_dofs(),
1002 local_vector()
1003 {
1004 }
1005
1006 void prepare(const Index cell)
1007 {
1008 BaseClass::prepare(cell);
1009
1010 // gather local solution dofs if required
1011 if(!sol_equals_conv)
1012 {
1013 this->local_sol_dofs.format();
1014 this->gather_vec_sol(this->local_sol_dofs, this->dof_mapping);
1015 }
1016 }
1017
1021 void compute_local_vector()
1022 {
1023 local_vector.format();
1024
1025 // compute local vector from local matrix and sol vector dofs
1026 if(!sol_equals_conv)
1027 {
1028 for(int i(0); i < this->num_local_dofs; ++i)
1029 for(int j(0); j < this->num_local_dofs; ++j)
1030 this->local_vector[i].add_mat_vec_mult(this->local_matrix(i,j), this->local_sol_dofs[j]);
1031 }
1032 else
1033 {
1034 for(int i(0); i < this->num_local_dofs; ++i)
1035 for(int j(0); j < this->num_local_dofs; ++j)
1036 this->local_vector[i].add_mat_vec_mult(this->local_matrix(i,j), this->local_conv_dofs[j]);
1037 }
1038 }
1039
1040 void assemble()
1041 {
1042 // assemble the local matrix
1043 BaseClass::assemble();
1044
1045 // compute the local vector from the matrix
1046 compute_local_vector();
1047 }
1048
1050 void scatter()
1051 {
1052 this->scatter_vec_rhs(this->local_vector, this->dof_mapping, this->alpha);
1053 }
1054 }; // class BurgersVeloMaterialBlockedVectorAssemblyJob::Task
1055 }; // class BurgersVeloMaterialBlockedVectorAssemblyJob<...>
1056
1075 template<typename Job_, typename DataType_, typename ViscFunc_, typename ViscDerFunc_>
1076 class BurgersVeloMaterialScalarAssemblyTaskBase :
1077 public BurgersVeloMaterialAssemblyTaskBase<Job_, DataType_, ViscFunc_>
1078 {
1079 public:
1080 typedef BurgersVeloMaterialAssemblyTaskBase<Job_, DataType_, ViscFunc_> BaseClass;
1081
1082 typedef DataType_ DataType;
1083
1084 using BaseClass::max_local_dofs;
1085 using BaseClass::num_local_dofs;
1086
1087 protected:
1089 typedef Tiny::Matrix<DataType, max_local_dofs, max_local_dofs> LocalMatrixType;
1090 LocalMatrixType local_matrix;
1091 ViscDerFunc_ visco_der_fun;
1092
1093 public:
1100 explicit BurgersVeloMaterialScalarAssemblyTaskBase(const Job_& job_) :
1101 BaseClass(job_),
1102 local_matrix(),
1103 visco_der_fun(job_.visc_der_fun)
1104 {
1105 }
1106
1113 void assemble_burgers_point(const DataType weight)
1114 {
1115 // assemble diffusion matrix?
1116 if(this->need_diff)
1117 {
1118 // assemble gradient-tensor diffusion
1119
1120 // test function loop
1121 for(int i(0); i < this->num_local_dofs; ++i)
1122 {
1123 // trial function loop
1124 for(int j(0); j < this->num_local_dofs; ++j)
1125 {
1126 local_matrix[i][j] += this->nu_loc * weight
1127 * Tiny::dot(this->space_data.phi[i].grad, this->space_data.phi[j].grad);
1128 }
1129 }
1130
1131 // \TODO: additional frechet term?
1132 }
1133
1134 // assemble convection?
1135 if(this->need_conv)
1136 {
1137 // test function loop
1138 for(int i(0); i < this->num_local_dofs; ++i)
1139 {
1140 // trial function loop
1141 for(int j(0); j < this->num_local_dofs; ++j)
1142 {
1143 local_matrix[i][j] += this->beta * weight
1144 * this->space_data.phi[i].value * Tiny::dot(this->loc_v, this->space_data.phi[j].grad);
1145 }
1146 }
1147 }
1148
1149 // assemble reaction?
1150 if(this->need_reac)
1151 {
1152 // test function loop
1153 for(int i(0); i < this->num_local_dofs; ++i)
1154 {
1155 // trial function loop
1156 for(int j(0); j < this->num_local_dofs; ++j)
1157 {
1158 local_matrix[i][j] += this->theta * weight
1159 * this->space_data.phi[i].value * this->space_data.phi[j].value;
1160 }
1161 }
1162 }
1163 }
1164
1171 void assemble_streamline_diffusion(const DataType weight)
1172 {
1173 // assemble streamline diffusion?
1174 if(this->need_streamdiff && (this->local_delta > this->tol_eps))
1175 {
1176 // test function loop
1177 for(int i(0); i < this->num_local_dofs; ++i)
1178 {
1179 // trial function loop
1180 for(int j(0); j < this->num_local_dofs; ++j)
1181 {
1182 local_matrix[i][j] += this->local_delta * weight
1183 * this->streamdiff_coeffs[i] * this->streamdiff_coeffs[j];
1184 }
1185 }
1186 }
1187 }
1188
1192 void assemble()
1193 {
1194 local_matrix.format();
1195
1196 // loop over all quadrature points and integrate
1197 for(int point(0); point < this->cubature_rule.get_num_points(); ++point)
1198 {
1199 // prepare trafo and space for cubature point
1200 this->prepare_point(point);
1201
1202 // precompute cubature weight
1203 const DataType weight = this->trafo_data.jac_det * this->cubature_rule.get_weight(point);
1204
1205 // assemble the Burgers operator
1206 this->assemble_burgers_point(weight);
1207
1208 // assembles the streamline diffusion stabilization
1209 this->assemble_streamline_diffusion(weight);
1210 } // continue with next cubature point
1211 }
1212 }; // class BurgersVeloMaterialScalarAssemblyTaskBase<...>
1213
1234 template<typename Matrix_, typename Space_, typename ViscFunc_, typename ViscDerFunc_, typename ConvVector_>
1235 class BurgersVeloMaterialScalarMatrixAssemblyJob :
1236 public BurgersVeloMaterialAssemblyJobBase<typename Matrix_::DataType, Space_, ViscFunc_, ViscDerFunc_, ConvVector_>
1237 {
1238 public:
1240 typedef Matrix_ MatrixType;
1242 typedef typename MatrixType::DataType DataType;
1243
1245 typedef BurgersVeloMaterialAssemblyJobBase<DataType, Space_, ViscFunc_, ViscDerFunc_, ConvVector_> BaseClass;
1246
1248 MatrixType& matrix;
1249
1250 public:
1266 explicit BurgersVeloMaterialScalarMatrixAssemblyJob(Matrix_& matrix_, const ConvVector_& conv_vector,
1267 const Space_& space_, const String& cubature_name,
1268 ViscFunc_ visc_fun, ViscDerFunc_ visc_der_fun) :
1269 BaseClass(conv_vector, space_, cubature_name, visc_fun, visc_der_fun),
1270 matrix(matrix_)
1271 {
1272 }
1273
1274 public:
1276 class Task :
1277 public BurgersVeloMaterialScalarAssemblyTaskBase<BurgersVeloMaterialScalarMatrixAssemblyJob, DataType, ViscFunc_, ViscDerFunc_>
1278 {
1279 public:
1280 typedef BurgersVeloMaterialScalarAssemblyTaskBase<BurgersVeloMaterialScalarMatrixAssemblyJob, DataType, ViscFunc_, ViscDerFunc_> BaseClass;
1281
1282 protected:
1284 typename MatrixType::ScatterAxpy scatter_matrix;
1285
1286 public:
1288 explicit Task(const BurgersVeloMaterialScalarMatrixAssemblyJob& job_) :
1289 BaseClass(job_),
1290 scatter_matrix(job_.matrix)
1291 {
1292 }
1293
1294 // prepare, assemble and finish are already implemented in the base classes
1295
1297 void scatter()
1298 {
1299 this->scatter_matrix(this->local_matrix, this->dof_mapping, this->dof_mapping, this->alpha);
1300 }
1301 }; // class BurgersVeloMaterialScalarMatrixAssemblyJob::Task
1302 }; // class BurgersVeloMaterialScalarMatrixAssemblyJob
1303
1324 template<typename Vector_, typename Space_, typename ViscoFunc_, typename ViscoDerFunc_, typename ConvVector_>
1325 class BurgersVeloMaterialScalarVectorAssemblyJob :
1326 public BurgersVeloMaterialAssemblyJobBase<typename Vector_::DataType, Space_, ViscoFunc_, ViscoDerFunc_, ConvVector_>
1327 {
1328 public:
1330 typedef Vector_ VectorType;
1332 typedef typename VectorType::DataType DataType;
1333
1335 typedef BurgersVeloMaterialAssemblyJobBase<DataType, Space_, ViscoFunc_, ViscoDerFunc_, ConvVector_> BaseClass;
1336
1338 VectorType& vector_rhs;
1339
1341 const VectorType& vector_sol;
1342
1343 public:
1364 explicit BurgersVeloMaterialScalarVectorAssemblyJob(Vector_& rhs_vector_, const Vector_& sol_vector_,
1365 const ConvVector_& conv_vector, const Space_& space_, const String& cubature_name) :
1366 BaseClass(conv_vector, space_, cubature_name),
1367 vector_rhs(rhs_vector_),
1368 vector_sol(sol_vector_)
1369 {
1370 XASSERTM(&rhs_vector_ != &sol_vector_, "rhs and solution vectors must not be the same object");
1371 }
1372
1373 public:
1375 class Task :
1376 public BurgersVeloMaterialScalarAssemblyTaskBase<BurgersVeloMaterialScalarVectorAssemblyJob, DataType, ViscoFunc_, ViscoDerFunc_>
1377 {
1378 public:
1379 typedef BurgersVeloMaterialScalarAssemblyTaskBase<BurgersVeloMaterialScalarVectorAssemblyJob, DataType, ViscoFunc_, ViscoDerFunc_> BaseClass;
1380
1381 using BaseClass::max_local_dofs;
1382
1383 protected:
1385 typename VectorType::GatherAxpy gather_vec_sol;
1387 typename VectorType::ScatterAxpy scatter_vec_rhs;
1388
1390 Tiny::Vector<DataType, max_local_dofs> local_sol_dofs;
1391
1393 Tiny::Vector<DataType, max_local_dofs> local_vector;
1394
1395 public:
1397 explicit Task(const BurgersVeloMaterialScalarVectorAssemblyJob& job_) :
1398 BaseClass(job_),
1399 gather_vec_sol(job_.vector_sol),
1400 scatter_vec_rhs(job_.vector_rhs),
1401 local_sol_dofs(),
1402 local_vector()
1403 {
1404 }
1405
1406 void prepare(const Index cell)
1407 {
1408 BaseClass::prepare(cell);
1409
1410 // gather local solution vector dofs
1411 this->local_sol_dofs.format();
1412 this->gather_vec_sol(this->local_sol_dofs, this->dof_mapping);
1413 }
1414
1418 void compute_local_vector()
1419 {
1420 // compute local vector from local matrix and sol vector dofs
1421 this->local_vector.format();
1422 for(int i(0); i < this->num_local_dofs; ++i)
1423 for(int j(0); j < this->num_local_dofs; ++j)
1424 this->local_vector[i] += this->local_matrix(i,j) * this->local_sol_dofs[j];
1425 //this->local_vector.set_mat_vec_mult(this->local_matrix, this->local_sol_dofs);
1426 }
1427
1428 void assemble()
1429 {
1430 // assemble the local matrix
1431 BaseClass::assemble();
1432
1433 // compute local vector from the matrix
1434 compute_local_vector();
1435 }
1436
1438 void scatter()
1439 {
1440 this->scatter_vec_rhs(this->local_vector, this->dof_mapping, this->alpha);
1441 }
1442 }; // class BurgersVeloMaterialScalarVectorAssemblyJob::Task
1443 }; // class BurgersVeloMaterialScalarVectorAssemblyJob<...>
1444 } // namespace Assembly
1445} // namespace FEAT
1446
1447#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