PolyDEAL
 
Loading...
Searching...
No Matches
packaged_operation_for_mg.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2014 - 2021 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
16#ifndef dealii_packaged_operation_for_mg_h
17#define dealii_packaged_operation_for_mg_h
18
19#include <deal.II/base/config.h>
20
22
24
25#include <functional>
26
28
29// Forward declarations:
30#ifndef DOXYGEN
31template <typename Number>
32class Vector;
33template <typename Range, typename Domain, typename Payload>
35template <typename Range = Vector<double>>
37#endif
38
39
104template <typename Range>
106{
107public:
114 {
115 apply = [](Range &) {
116 Assert(false,
117 ExcMessage(
118 "Uninitialized PackagedOperationMG<Range>::apply called"));
119 };
120
121 apply_add = [](Range &) {
122 Assert(false,
123 ExcMessage(
124 "Uninitialized PackagedOperationMG<Range>::apply_add called"));
125 };
126
127 reinit_vector = [](Range &, bool) {
128 Assert(false,
129 ExcMessage(
130 "Uninitialized PackagedOperationMG<Range>::reinit_vector "
131 "method called"));
132 };
133 }
134
139
149 PackagedOperationMG(const Range &u)
150 {
151 *this = u;
152 }
153
159
170 operator=(const Range &u)
171 {
172 apply = [&u](Range &v) { v = u; };
173
174 apply_add = [&u](Range &v) { v += u; };
175
176 reinit_vector = [&u](Range &v, bool omit_zeroing_entries) {
177 v.reinit(u, omit_zeroing_entries);
178 };
179
180 return *this;
181 }
182
189 operator Range() const
190 {
191 Range result_vector;
192
193 reinit_vector(result_vector, /*bool omit_zeroing_entries=*/true);
194 apply(result_vector);
195
196 return result_vector;
197 }
198
203
209 {
210 *this = *this + second_comp;
211 return *this;
212 }
213
220 {
221 *this = *this - second_comp;
222 return *this;
223 }
224
230 operator+=(const Range &offset)
231 {
232 *this = *this + PackagedOperationMG<Range>(offset);
233 return *this;
234 }
235
241 operator-=(const Range &offset)
242 {
243 *this = *this - PackagedOperationMG<Range>(offset);
244 return *this;
245 }
246
251 operator*=(typename Range::value_type number)
252 {
253 *this = *this * number;
254 return *this;
255 }
257
262 std::function<void(Range &v)> apply;
263
268 std::function<void(Range &v)> apply_add;
269
277 std::function<void(Range &v, bool omit_zeroing_entries)> reinit_vector;
278};
279
280
285
294template <typename Range>
296operator+(const PackagedOperationMG<Range> &first_comp,
297 const PackagedOperationMG<Range> &second_comp)
298{
299 PackagedOperationMG<Range> return_comp;
300
301 return_comp.reinit_vector = first_comp.reinit_vector;
302
303 // ensure to have valid PackagedOperationMG objects by catching first_comp and
304 // second_comp by value
305
306 return_comp.apply = [first_comp, second_comp](Range &v) {
307 first_comp.apply(v);
308 second_comp.apply_add(v);
309 };
310
311 return_comp.apply_add = [first_comp, second_comp](Range &v) {
312 first_comp.apply_add(v);
313 second_comp.apply_add(v);
314 };
315
316 return return_comp;
317}
318
327template <typename Range>
329operator-(const PackagedOperationMG<Range> &first_comp,
330 const PackagedOperationMG<Range> &second_comp)
331{
332 PackagedOperationMG<Range> return_comp;
333
334 return_comp.reinit_vector = first_comp.reinit_vector;
335
336 // ensure to have valid PackagedOperationMG objects by catching first_comp and
337 // second_comp by value
338
339 return_comp.apply = [first_comp, second_comp](Range &v) {
340 second_comp.apply(v);
341 v *= -1.;
342 first_comp.apply_add(v);
343 };
344
345 return_comp.apply_add = [first_comp, second_comp](Range &v) {
346 first_comp.apply_add(v);
347 v *= -1.;
348 second_comp.apply_add(v);
349 v *= -1.;
350 };
351
352 return return_comp;
353}
354
363template <typename Range>
366 typename Range::value_type number)
367{
368 PackagedOperationMG<Range> return_comp;
369
370 return_comp.reinit_vector = comp.reinit_vector;
371
372 // the trivial case: number is zero
373 if (number == 0.)
374 {
375 return_comp.apply = [](Range &v) { v = 0.; };
376
377 return_comp.apply_add = [](Range &) {};
378 }
379 else
380 {
381 return_comp.apply = [comp, number](Range &v) {
382 comp.apply(v);
383 v *= number;
384 };
385
386 return_comp.apply_add = [comp, number](Range &v) {
387 v /= number;
388 comp.apply_add(v);
389 v *= number;
390 };
391 }
392
393 return return_comp;
394}
395
404template <typename Range>
406operator*(typename Range::value_type number,
407 const PackagedOperationMG<Range> &comp)
408{
409 return comp * number;
410}
411
420template <typename Range>
422operator+(const PackagedOperationMG<Range> &comp, const Range &offset)
423{
424 return comp + PackagedOperationMG<Range>(offset);
425}
426
435template <typename Range>
437operator+(const Range &offset, const PackagedOperationMG<Range> &comp)
438{
439 return PackagedOperationMG<Range>(offset) + comp;
440}
441
450template <typename Range>
452operator-(const PackagedOperationMG<Range> &comp, const Range &offset)
453{
454 return comp - PackagedOperationMG<Range>(offset);
455}
456
457
467template <typename Range>
469operator-(const Range &offset, const PackagedOperationMG<Range> &comp)
470{
471 return PackagedOperationMG<Range>(offset) - comp;
472}
473
475
476
481
482namespace internal
483{
484 namespace PackagedOperationImplementation
485 {
486 // Poor man's trait class that determines whether type T is a vector:
487 // FIXME: Implement this as a proper type trait - similar to
488 // isBlockVector
489
490 template <typename T>
491 class has_vector_interface
492 {
493 template <typename C>
494 static std::false_type
495 test(...);
496
497 template <typename C>
498 static std::true_type
499 test(decltype(&C::operator+=),
500 decltype(&C::operator-=),
501 decltype(&C::l2_norm));
502
503 public:
504 // type is std::true_type if Matrix provides vmult_add and Tvmult_add,
505 // otherwise it is std::false_type
506
507 using type = decltype(test<T>(nullptr, nullptr, nullptr));
508 }; // namespace
509 } // namespace PackagedOperationImplementation
510} // namespace internal
511
512
527template <typename Range,
528 typename = typename std::enable_if<
530 Range>::type::value>::type>
532operator+(const Range &u, const Range &v)
533{
534 PackagedOperationMG<Range> return_comp;
535
536 // ensure to have valid PackagedOperationMG objects by catching op by value
537 // u is caught by reference
538
539 return_comp.reinit_vector = [&u](Range &x, bool omit_zeroing_entries) {
540 x.reinit(u, omit_zeroing_entries);
541 };
542
543 return_comp.apply = [&u, &v](Range &x) {
544 x = u;
545 x += v;
546 };
547
548 return_comp.apply_add = [&u, &v](Range &x) {
549 x += u;
550 x += v;
551 };
552
553 return return_comp;
554}
555
556
572template <typename Range,
573 typename = typename std::enable_if<
575 Range>::type::value>::type>
577operator-(const Range &u, const Range &v)
578{
579 PackagedOperationMG<Range> return_comp;
580
581 // ensure to have valid PackagedOperationMG objects by catching op by value
582 // u is caught by reference
583
584 return_comp.reinit_vector = [&u](Range &x, bool omit_zeroing_entries) {
585 x.reinit(u, omit_zeroing_entries);
586 };
587
588 return_comp.apply = [&u, &v](Range &x) {
589 x = u;
590 x -= v;
591 };
592
593 return_comp.apply_add = [&u, &v](Range &x) {
594 x += u;
595 x -= v;
596 };
597
598 return return_comp;
599}
600
601
616template <typename Range,
617 typename = typename std::enable_if<
619 Range>::type::value>::type>
621operator*(const Range &u, typename Range::value_type number)
622{
623 return PackagedOperationMG<Range>(u) * number;
624}
625
626
641template <typename Range,
642 typename = typename std::enable_if<
644 Range>::type::value>::type>
646operator*(typename Range::value_type number, const Range &u)
647{
648 return number * PackagedOperationMG<Range>(u);
649}
650
651
669template <typename Range, typename Domain, typename Payload>
671operator*(const LinearOperatorMG<Range, Domain, Payload> &op, const Domain &u)
672{
673 PackagedOperationMG<Range> return_comp;
674
675 return_comp.reinit_vector = op.reinit_range_vector;
676
677 // ensure to have valid PackagedOperationMG objects by catching op by value
678 // u is caught by reference
679
680 return_comp.apply = [op, &u](Range &v) { op.vmult(v, u); };
681
682 return_comp.apply_add = [op, &u](Range &v) { op.vmult_add(v, u); };
683
684 return return_comp;
685}
686
687
705template <typename Range, typename Domain, typename Payload>
708{
709 PackagedOperationMG<Range> return_comp;
710
711 return_comp.reinit_vector = op.reinit_domain_vector;
712
713 // ensure to have valid PackagedOperationMG objects by catching op by value
714 // u is caught by reference
715
716 return_comp.apply = [op, &u](Domain &v) { op.Tvmult(v, u); };
717
718 return_comp.apply_add = [op, &u](Domain &v) { op.Tvmult_add(v, u); };
719
720 return return_comp;
721}
722
723
732template <typename Range, typename Domain, typename Payload>
735 const PackagedOperationMG<Domain> &comp)
736{
737 PackagedOperationMG<Range> return_comp;
738
739 return_comp.reinit_vector = op.reinit_range_vector;
740
741 // ensure to have valid PackagedOperationMG objects by catching op by value
742 // u is caught by reference
743
744 return_comp.apply = [op, comp](Domain &v) {
745 GrowingVectorMemory<Range> vector_memory;
746
747 typename VectorMemory<Range>::Pointer i(vector_memory);
748 op.reinit_domain_vector(*i, /*bool omit_zeroing_entries =*/true);
749
750 comp.apply(*i);
751 op.vmult(v, *i);
752 };
753
754 return_comp.apply_add = [op, comp](Domain &v) {
755 GrowingVectorMemory<Range> vector_memory;
756
757 typename VectorMemory<Range>::Pointer i(vector_memory);
758 op.reinit_range_vector(*i, /*bool omit_zeroing_entries =*/true);
759
760 comp.apply(*i);
761 op.vmult_add(v, *i);
762 };
763
764 return return_comp;
765}
766
767
776template <typename Range, typename Domain, typename Payload>
780{
781 PackagedOperationMG<Range> return_comp;
782
783 return_comp.reinit_vector = op.reinit_domain_vector;
784
785 // ensure to have valid PackagedOperationMG objects by catching op by value
786 // u is caught by reference
787
788 return_comp.apply = [op, comp](Domain &v) {
789 GrowingVectorMemory<Range> vector_memory;
790
791 typename VectorMemory<Range>::Pointer i(vector_memory);
792 op.reinit_range_vector(*i, /*bool omit_zeroing_entries =*/true);
793
794 comp.apply(*i);
795 op.Tvmult(v, *i);
796 };
797
798 return_comp.apply_add = [op, comp](Domain &v) {
799 GrowingVectorMemory<Range> vector_memory;
800
801 typename VectorMemory<Range>::Pointer i(vector_memory);
802 op.reinit_range_vector(*i, /*bool omit_zeroing_entries =*/true);
803
804 comp.apply(*i);
805 op.Tvmult_add(v, *i);
806 };
807
808 return return_comp;
809}
810
812
814
815#endif
std::function< void(Range &v, bool omit_zeroing_entries)> reinit_range_vector
std::function< void(Range &v, const Domain &u)> vmult_add
std::function< void(Domain &v, const Range &u)> Tvmult_add
std::function< void(Domain &v, bool omit_zeroing_entries)> reinit_domain_vector
std::function< void(Domain &v, const Range &u)> Tvmult
std::function< void(Range &v, const Domain &u)> vmult
std::function< void(Range &v, bool omit_zeroing_entries)> reinit_vector
PackagedOperationMG< Range > & operator=(const PackagedOperationMG< Range > &)=default
PackagedOperationMG< Range > & operator-=(const PackagedOperationMG< Range > &second_comp)
PackagedOperationMG< Range > & operator-=(const Range &offset)
PackagedOperationMG< Range > & operator+=(const PackagedOperationMG< Range > &second_comp)
PackagedOperationMG(const PackagedOperationMG< Range > &)=default
PackagedOperationMG< Range > & operator+=(const Range &offset)
std::function< void(Range &v)> apply_add
PackagedOperationMG< Range > & operator*=(typename Range::value_type number)
std::function< void(Range &v)> apply
PackagedOperationMG< Range > & operator=(const Range &u)
std::enable_if_t< std::is_floating_point_v< T > &&std::is_floating_point_v< U >, typename ProductType< std::complex< T >, std::complex< U > >::type > operator*(const std::complex< T > &left, const std::complex< U > &right)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
BarycentricPolynomial< dim, Number1 > operator-(const Number2 &a, const BarycentricPolynomial< dim, Number1 > &bp)
BarycentricPolynomial< dim, Number1 > operator+(const Number2 &a, const BarycentricPolynomial< dim, Number1 > &bp)