FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
burgers_assembler_carreau.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8#include <algorithm>
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>
14
15namespace FEAT
16{
17 namespace Assembly
18 {
62 template<typename DataType_, typename IndexType_, int dim_>
64 {
65 public:
67 typedef DataType_ DataType;
68
71
72
73 bool diff;
74
75 bool frechet_diff;
76
78 //DataType_ nu;
79
81 DataType_ theta;
82
84 DataType_ beta;
85
87 DataType_ frechet_beta;
88
90 DataType_ sd_delta;
91
93 DataType_ sd_nu;
94
96 DataType_ sd_v_norm;
97
99 DataType_ mu_inf, mu_0, lambda, n, a, reg_eps;
100
103 deformation(true),
104 diff(true),
105 frechet_diff(false),
106 theta(DataType_(0)),
107 beta(DataType_(0)),
108 frechet_beta(DataType_(0)),
109 sd_delta(DataType_(0)),
110 sd_nu(DataType_(0)),
111 sd_v_norm(DataType_(0)),
112 mu_inf(DataType_(0.0)),
113 mu_0(DataType_(0.01)),
114 lambda(DataType_(1.0)),
115 n(DataType_(0.31)),
116 a(DataType_(2.0)),
117 reg_eps(DataType_(1e-100))
118 {
119 }
120
139 template<typename Space_, typename CubatureFactory_>
143 const Space_& space,
144 const CubatureFactory_& cubature_factory,
145 const DataType_ scale = DataType_(1)
146 ) const
147 {
148 // validate matrix and vector dimensions
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");
152
155
156 // tolerance: sqrt(eps)
157 const DataType tol_eps = Math::sqrt(Math::eps<DataType>());
158
159 // first of all, let's see what we have to assemble
160
161 const bool need_conv = (Math::abs(beta) > DataType(0));
162 const bool need_conv_frechet = (Math::abs(frechet_beta) > DataType(0));
163 const bool need_reac = (Math::abs(theta) > DataType(0));
164 const bool need_streamdiff = (Math::abs(sd_delta) > DataType(0)) && (sd_v_norm > tol_eps);
165
166 // define our assembly traits
168
169 // fetch our trafo
170 const typename AsmTraits::TrafoType& trafo = space.get_trafo();
171
172 // create a trafo evaluator
173 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
174
175 // create a space evaluator and evaluation data
176 typename AsmTraits::SpaceEvaluator space_eval(space);
177
178 // create a dof-mapping
179 typename AsmTraits::DofMapping dof_mapping(space);
180
181 // create trafo evaluation data
182 typename AsmTraits::TrafoEvalData trafo_data;
183
184 // create space evaluation data
185 typename AsmTraits::SpaceEvalData space_data;
186
187 // create cubature rule
188 typename AsmTraits::CubatureRuleType cubature_rule(Cubature::ctor_factory, cubature_factory);
189
190 // create matrix scatter-axpy
191 typename MatrixType::ScatterAxpy scatter_matrix(matrix);
192
193 // create convection gather-axpy
194 typename VectorType::GatherAxpy gather_conv(convect);
195
196 // get maximum number of local dofs
197 static constexpr int max_local_dofs = AsmTraits::max_local_test_dofs;
198
199 // create local matrix data
200 typedef Tiny::Matrix<DataType, dim_, dim_> MatrixValue;
202 LocalMatrixType local_matrix;
203
204 // create local vector data
205 typedef Tiny::Vector<DataType, dim_> VectorValue;
206 typedef Tiny::Vector<VectorValue, max_local_dofs> LocalVectorType;
207
208 // local convection field dofs
209 LocalVectorType local_conv_dofs;
210
211 // our local velocity value
212 VectorValue loc_v, mean_v;
213
214 // our local velocity gradient
215 MatrixValue loc_grad_v;
216 MatrixValue strain_rate_tensor_2;
217
218 loc_v.format();
219 mean_v.format();
220 loc_grad_v.format();
221
222 // compute reference element barycentre
224 for(int i(0); i < dim_; ++i)
225 barycentre[i] = Shape::ReferenceCell<typename Space_::ShapeType>::template centre<DataType>(i);
226
227 // our local streamline diffusion coefficients
229 streamdiff_coeffs.format();
230
231 // our local delta for streamline diffusion
232 DataType local_delta = DataType(0);
233
234 // loop over all cells of the mesh
235 for(typename AsmTraits::CellIterator cell(trafo_eval.begin()); cell != trafo_eval.end(); ++cell)
236 {
237 // prepare trafo evaluator
238 trafo_eval.prepare(cell);
239
240 // prepare space evaluator
241 space_eval.prepare(trafo_eval);
242
243 // initialize dof-mapping
244 dof_mapping.prepare(cell);
245
246 // fetch number of local dofs
247 const int num_loc_dofs = space_eval.get_num_local_dofs();
248
249 // gather our local convection dofs
250 local_conv_dofs.format();
251 gather_conv(local_conv_dofs, dof_mapping);
252
253 // compute mesh width if necessary
254 if(need_streamdiff)
255 {
256 // reset local delta
257 local_delta = DataType(0);
258
259 // evaluate trafo and space at barycentre
260 trafo_eval(trafo_data, barycentre);
261 space_eval(space_data, trafo_data);
262
263 // compute velocity at barycentre
264 mean_v.format();
265 for(int i(0); i < num_loc_dofs; ++i)
266 mean_v.axpy(space_data.phi[i].value, local_conv_dofs[i]);
267
268 // compute norm of mean velocity
269 const DataType local_norm_v = mean_v.norm_euclid();
270
271 // do we have a non-zero velocity?
272 if(local_norm_v > tol_eps)
273 {
274 // compute local mesh width w.r.t. mean velocity
275 const DataType local_h = trafo_eval.width_directed(mean_v) * local_norm_v;
276
277 // compute local Re_T
278 const DataType local_re = (local_norm_v * local_h) / this->sd_nu;
279
280 // compute local delta
281 local_delta = this->sd_delta * (local_h / this->sd_v_norm) * (DataType(2)*local_re) / (DataType(1) + local_re);
282 }
283 }
284
285 // format our local matrix and vector
286 local_matrix.format();
287
288 // loop over all quadrature points and integrate
289 for(int point(0); point < cubature_rule.get_num_points(); ++point)
290 {
291 // compute trafo data
292 trafo_eval(trafo_data, cubature_rule.get_point(point));
293
294 // compute basis function data
295 space_eval(space_data, trafo_data);
296
297 // pre-compute cubature weight
298 const DataType weight = trafo_data.jac_det * cubature_rule.get_weight(point);
299
300 // evaluate convection function and its gradient (if required)
301 if(need_conv || need_streamdiff)
302 {
303 loc_v.format();
304 for(int i(0); i < num_loc_dofs; ++i)
305 {
306 // update velocity value
307 loc_v.axpy(space_data.phi[i].value, local_conv_dofs[i]);
308 }
309 }
310 // always needed for material model
311 loc_grad_v.format();
312 for(int i(0); i < num_loc_dofs; ++i)
313 {
314 // update velocity gradient
315 loc_grad_v.add_outer_product(local_conv_dofs[i], space_data.phi[i].grad);
316 }
317
318
319 // evaluate streamline diffusion coefficients
320 if(need_streamdiff)
321 {
322 for(int i(0); i < num_loc_dofs; ++i)
323 {
324 streamdiff_coeffs[i] = Tiny::dot(loc_v, space_data.phi[i].grad);
325 }
326 }
327
328 //calculate nu_loc
329
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();
333 DataType_ nu_loc = mu_inf + (mu_0 - mu_inf) * Math::pow((DataType_(1.0) + Math::pow(lambda*gamma_dot, a)), (n-DataType(1.0)) / a);
334
335
336 // assemble diffusion matrix?
337 if(diff && !deformation)
338 {
339 // assemble gradient-tensor diffusion
340
341 // test function loop
342 for(int i(0); i < num_loc_dofs; ++i)
343 {
344 // trial function loop
345 for(int j(0); j < num_loc_dofs; ++j)
346 {
347 // compute scalar value
348 const DataType value = nu_loc * weight * Tiny::dot(space_data.phi[i].grad, space_data.phi[j].grad);
349
350 // update local matrix
351 local_matrix[i][j].add_scalar_main_diag(value);
352 }
353 }
354 }
355 else if(diff && deformation)
356 {
357
358 // assemble deformation-tensor diffusion
359
360 // test function loop
361 for(int i(0); i < num_loc_dofs; ++i)
362 {
363 // trial function loop
364 for(int j(0); j < num_loc_dofs; ++j)
365 {
366 // compute inner product of grad(phi) and grad(psi)
367 const DataType value = nu_loc * weight * Tiny::dot(space_data.phi[j].grad, space_data.phi[i].grad);
368
369 // update local matrix
370 local_matrix[i][j].add_scalar_main_diag(value);
371
372 // add outer product of grad(phi) and grad(psi)
373 local_matrix[i][j].add_outer_product(space_data.phi[j].grad, space_data.phi[i].grad, nu_loc * weight);
374 }
375 }
376 }
377
378 if(frechet_diff)
379 {
381 const DataType_ mu_prime = (mu_0 - mu_inf) * ((n-DataType_(1.0)) / a) *
382 Math::pow( DataType(1.0) + Math::pow(lambda*gamma_dot, a), ((n-DataType_(1.0) -a) / a)) *
383 a * lambda * Math::pow(lambda*gamma_dot, a-DataType(1.0));
384 const DataType fac = mu_prime / (gamma_dot + reg_eps);
385 //std::cout << fac ;
386 // test function loop
387 for(int i(0); i < num_loc_dofs; ++i)
388 {
389 VectorValue du_grad_phi;
390 du_grad_phi.set_mat_vec_mult(strain_rate_tensor_2, space_data.phi[i].grad);
391
392 // trial function loop
393 for(int j(0); j < num_loc_dofs; ++j)
394 {
395 VectorValue du_grad_psi;
396 du_grad_psi.set_mat_vec_mult(strain_rate_tensor_2, space_data.phi[j].grad);
397 // add outer product of grad(phi) and grad(psi)
398 local_matrix[i][j].add_outer_product(du_grad_phi, du_grad_psi, fac * weight);
399 }
400 }
401 }
402
403
404
405
406 // assemble convection?
407 if(need_conv)
408 {
409 // test function loop
410 for(int i(0); i < num_loc_dofs; ++i)
411 {
412 // trial function loop
413 for(int j(0); j < num_loc_dofs; ++j)
414 {
415 // compute scalar value
416 const DataType value = beta * weight * space_data.phi[i].value * Tiny::dot(loc_v, space_data.phi[j].grad);
417
418 // update local matrix
419 local_matrix[i][j].add_scalar_main_diag(value);
420 }
421 }
422 }
423
424 // assemble convection Frechet?
425 if(need_conv_frechet)
426 {
427
428 // test function loop
429 for(int i(0); i < num_loc_dofs; ++i)
430 {
431 // trial function loop
432 for(int j(0); j < num_loc_dofs; ++j)
433 {
434 // compute scalar value
435 const DataType value = frechet_beta * weight * space_data.phi[i].value * space_data.phi[j].value;
436
437 // update local matrix
438 local_matrix[i][j].axpy(value, loc_grad_v);
439 }
440 }
441 }
442
443 // assemble reaction?
444 if(need_reac)
445 {
446 // test function loop
447 for(int i(0); i < num_loc_dofs; ++i)
448 {
449 // trial function loop
450 for(int j(0); j < num_loc_dofs; ++j)
451 {
452 // compute scalar value
453 const DataType value = theta * weight * space_data.phi[i].value * space_data.phi[j].value;
454
455 // update local matrix
456 local_matrix[i][j].add_scalar_main_diag(value);
457 }
458 }
459 }
460
461 // assemble streamline diffusion?
462 if(need_streamdiff && (local_delta > tol_eps))
463 {
464 // test function loop
465 for(int i(0); i < num_loc_dofs; ++i)
466 {
467 // trial function loop
468 for(int j(0); j < num_loc_dofs; ++j)
469 {
470 // compute scalar value
471 const DataType value = local_delta * weight * streamdiff_coeffs[i] * streamdiff_coeffs[j];
472
473 // update local matrix
474 local_matrix[i][j].add_scalar_main_diag(value);
475 }
476 }
477 }
478
479 // continue with next cubature point
480 }
481
482 // scatter into matrix
483 scatter_matrix(local_matrix, dof_mapping, dof_mapping, scale);
484
485 // finish dof mapping
486 dof_mapping.finish();
487
488 // finish evaluators
489 space_eval.finish();
490 trafo_eval.finish();
491 }
492 }
493
515 template<typename Space_, typename CubatureFactory_>
520 const Space_& space,
521 const CubatureFactory_& cubature_factory,
522 const DataType_ scale = DataType_(1)
523 ) const
524 {
525 // validate matrix and vector dimensions
526 XASSERTM(vector.size() == space.get_num_dofs(), "invalid vector size");
527 XASSERTM(convect.size() == space.get_num_dofs(), "invalid vector size");
528
530
531
532
533 // first of all, let's see what we have to assemble
534 const bool need_conv = (Math::abs(beta) > DataType(0));
535 //const bool need_conv_frechet = (frechet_beta > DataType(0));
536 const bool need_reac = (Math::abs(theta) > DataType(0));
537
538 // define our assembly traits
540
541 // fetch our trafo
542 const typename AsmTraits::TrafoType& trafo = space.get_trafo();
543
544 // create a trafo evaluator
545 typename AsmTraits::TrafoEvaluator trafo_eval(trafo);
546
547 // create a space evaluator and evaluation data
548 typename AsmTraits::SpaceEvaluator space_eval(space);
549
550 // create a dof-mapping
551 typename AsmTraits::DofMapping dof_mapping(space);
552
553 // create trafo evaluation data
554 typename AsmTraits::TrafoEvalData trafo_data;
555
556 // create space evaluation data
557 typename AsmTraits::SpaceEvalData space_data;
558
559 // create cubature rule
560 typename AsmTraits::CubatureRuleType cubature_rule(Cubature::ctor_factory, cubature_factory);
561
562 // create vector-scatter-axpy (if needed)
563 typename VectorType::ScatterAxpy scatter_vector(vector);
564
565 // create convection gather-axpy
566 typename VectorType::GatherAxpy gather_conv(convect);
567
568 // create primal gather-axpy
569 typename VectorType::GatherAxpy gather_prim(primal);
570
571 // get maximum number of local dofs
572 static constexpr int max_local_dofs = AsmTraits::max_local_test_dofs;
573
574 // create local vector data
575 typedef Tiny::Vector<DataType, dim_> VectorValue;
576 typedef Tiny::Vector<VectorValue, max_local_dofs> LocalVectorType;
577 LocalVectorType local_vector;
578
579 // local convection field dofs
580 LocalVectorType local_conv_dofs;
581
582 // local primal vector dofs
583 LocalVectorType local_prim_dofs;
584
585 // our local velocity value
587
588 // our local velocity gradient
590
591 Tiny::Matrix<DataType, dim_, dim_> strain_rate_tensor_2;
592
593 loc_v.format();
594 loc_grad_v.format();
595
596 // loop over all cells of the mesh
597 for(typename AsmTraits::CellIterator cell(trafo_eval.begin()); cell != trafo_eval.end(); ++cell)
598 {
599 // prepare trafo evaluator
600 trafo_eval.prepare(cell);
601
602 // prepare space evaluator
603 space_eval.prepare(trafo_eval);
604
605 // initialize dof-mapping
606 dof_mapping.prepare(cell);
607
608 // fetch number of local dofs
609 const int num_loc_dofs = space_eval.get_num_local_dofs();
610
611 // gather our local convection dofs
612 local_conv_dofs.format();
613 gather_conv(local_conv_dofs, dof_mapping);
614
615 // gather our local primal dofs
616 local_prim_dofs.format();
617 gather_prim(local_prim_dofs, dof_mapping);
618
619 // format our local vector
620 local_vector.format();
621
622 // loop over all quadrature points and integrate
623 for(int point(0); point < cubature_rule.get_num_points(); ++point)
624 {
625 // compute trafo data
626 trafo_eval(trafo_data, cubature_rule.get_point(point));
627
628 // compute basis function data
629 space_eval(space_data, trafo_data);
630
631 // pre-compute cubature weight
632 const DataType weight = trafo_data.jac_det * cubature_rule.get_weight(point);
633
634 // evaluate convection function and its gradient (if required)
635 if(need_conv)
636 {
637 loc_v.format();
638 for(int i(0); i < num_loc_dofs; ++i)
639 {
640 // update velocity value
641 loc_v.axpy(space_data.phi[i].value, local_conv_dofs[i]);
642 }
643 }
644 if(diff || frechet_diff)
645 {
646
647 loc_grad_v.format();
648 for(int i(0); i < num_loc_dofs; ++i)
649 {
650 // update velocity gradient
651 loc_grad_v.add_outer_product(local_conv_dofs[i], space_data.phi[i].grad);
652 }
653
654 }
655
656 loc_grad_v.format();
657 for(int i(0); i < num_loc_dofs; ++i)
658 {
659 // update velocity gradient
660 loc_grad_v.add_outer_product(local_conv_dofs[i], space_data.phi[i].grad);
661 }
662
663 //calculate nu_loc
664 strain_rate_tensor_2.set_transpose(loc_grad_v);
665 strain_rate_tensor_2.axpy(DataType(1.0), loc_grad_v);
666 DataType_ gamma_dot = Math::sqrt(0.5)*strain_rate_tensor_2.norm_frobenius();
667 DataType_ nu_loc = mu_inf + (mu_0 - mu_inf) * Math::pow((DataType_(1.0) + Math::pow(lambda*gamma_dot, a)), (n-DataType(1.0)) / a);
668
669
670 // assemble diffusion matrix?
671 if(diff && !deformation)
672 {
673 // assemble gradient-tensor diffusion
674
675 // test function loop
676 for(int i(0); i < num_loc_dofs; ++i)
677 {
678 // trial function loop
679 for(int j(0); j < num_loc_dofs; ++j)
680 {
681 // compute scalar value
682 const DataType value = nu_loc * weight * Tiny::dot(space_data.phi[i].grad, space_data.phi[j].grad);
683
684 // update local vector
685 local_vector[i].axpy(value, local_prim_dofs[j]);
686 }
687 }
688 }
689 else if(diff && deformation)
690 {
691 // assemble deformation-tensor diffusion
692
693 // test function loop
694 for(int i(0); i < num_loc_dofs; ++i)
695 {
696 // trial function loop
697 for(int j(0); j < num_loc_dofs; ++j)
698 {
699 // compute inner product of grad(phi) and grad(psi)
700 const DataType value1 = nu_loc * weight * Tiny::dot(space_data.phi[i].grad, space_data.phi[j].grad);
701
702 // compute outer product of grad(phi) and grad(psi)
703 const DataType value2 = nu_loc * weight * Tiny::dot(local_prim_dofs[j], space_data.phi[i].grad);
704
705 // update local vector
706 local_vector[i].axpy(value1, local_prim_dofs[j]);
707 local_vector[i].axpy(value2, space_data.phi[j].grad);
708 }
709 }
710 }
711
712 // assemble convection?
713 if(need_conv)
714 {
715 // test function loop
716 for(int i(0); i < num_loc_dofs; ++i)
717 {
718 // trial function loop
719 for(int j(0); j < num_loc_dofs; ++j)
720 {
721 // compute scalar value
722 const DataType value = beta * weight * space_data.phi[i].value * Tiny::dot(loc_v, space_data.phi[j].grad);
723
724 // update local vector
725 local_vector[i].axpy(value, local_prim_dofs[j]);
726 }
727 }
728 }
729
730 // assemble reaction?
731 if(need_reac)
732 {
733 // test function loop
734 for(int i(0); i < num_loc_dofs; ++i)
735 {
736 // trial function loop
737 for(int j(0); j < num_loc_dofs; ++j)
738 {
739 // compute scalar value
740 const DataType value = theta * weight * space_data.phi[i].value * space_data.phi[j].value;
741
742 // update local vector
743 local_vector[i].axpy(value, local_prim_dofs[j]);
744 }
745 }
746 }
747
748 // continue with next cubature point
749 }
750
751 // scatter into vector
752 scatter_vector(local_vector, dof_mapping, scale);
753
754 // finish dof mapping
755 dof_mapping.finish();
756
757 // finish evaluators
758 space_eval.finish();
759 trafo_eval.finish();
760 }
761 }
762
770 {
771 const auto* vals = convect.elements();
772 DataType_ r = DataType(0);
773 for(Index i(0); i < convect.size(); ++i)
774 r = Math::max(r, vals[i].norm_euclid());
775 this->sd_v_norm = r;
776 }
777
787 template<typename LocalVector_, typename Mirror_>
789 {
790 this->set_sd_v_norm(convect.local());
791 const auto* gate = convect.get_gate();
792 if(gate != nullptr)
793 this->sd_v_norm = gate->max(this->sd_v_norm);
794 }
795 }; // class BurgersAssembler<...>
796 } // namespace Assembly
797} // namespace FEAT
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Common single-space assembly traits class template.
Definition: asm_traits.hpp:83
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.
bool deformation
specifies whether to use the deformation tensor
DataType_ frechet_beta
scaling parameter for Frechet derivative of convective operator K'
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.
Definition: gate.hpp:619
Global vector wrapper class template.
Definition: vector.hpp:68
const GateType * get_gate() const
Returns a const pointer to the internal gate of the vector.
Definition: vector.hpp:148
LocalVector_ & local()
Returns a reference to the internal local LAFEM vector object.
Definition: vector.hpp:121
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.
Definition: math.hpp:300
T_ abs(T_ x)
Returns the absolute value.
Definition: math.hpp:275
T_ pow(T_ x, T_ y)
Returns x raised to the power of y.
Definition: math.hpp:643
T_ max(T_ a, T_ b)
Returns the maximum of two values.
Definition: math.hpp:137
CUDA_HOST_DEVICE T_ dot(const T_ &a, const T_ &b)
Computes the dot-product of two scalars.
FEAT namespace.
Definition: adjactor.hpp:12
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
Reference cell traits structure.
Definition: shape.hpp:230