Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
BilinearWeakSum.h
Go to the documentation of this file.
1/* This file is part of MoDELib, the Mechanics Of Defects Evolution Library.
2 *
3 *
4 * MoDELib is distributed without any warranty under the
5 * GNU General Public License (GPL) v2 <http://www.gnu.org/licenses/>.
6 */
7
8#ifndef model_BilinearWeakSum_H_
9#define model_BilinearWeakSum_H_
10
11#include <LowRankBilinear.h>
12#include <iterator>
13#include <type_traits>
14
16#include <memory>
17#include <stdexcept>
18
19namespace model
20{
21
22 template <typename T1,typename T2>
23 struct BilinearWeakSum : public BilinearWeakExpression<BilinearWeakSum<T1,T2> >
24 {
25
26 static_assert(std::is_same<typename T1::TrialFunctionType,typename T2::TrialFunctionType>::value,"YOU ARE SUMMING BilinearWeakForms OF DIFFERENT TRIALFUNCTIONS.");
27 typedef typename T1::TrialFunctionType TrialFunctionType;
28
29 const std::shared_ptr<T1> op1;
30
31 const std::shared_ptr<T2> op2;
32 BilinearWeakSum(std::shared_ptr<T1> x, std::shared_ptr<T2> y) :
33 op1(std::move(x)), op2(std::move(y))
34 {
35 if(!op1 || !op2)
36 {
37 throw std::invalid_argument("Null FEM expression operand.");
38 }
39 }
40
41 std::vector<Eigen::Triplet<double> > globalTriplets() const
42 {
43 if(!(op2->field().sameField(field())))
44 {
45 throw std::runtime_error("Cannot assemble expressions from different FEM field instances.");
46 }
47 std::vector<Eigen::Triplet<double> > gt1=op1->globalTriplets();
48 std::vector<Eigen::Triplet<double> > gt2=op2->globalTriplets();
49 gt1.insert(
50 gt1.end(),
51 std::make_move_iterator(gt2.begin()),
52 std::make_move_iterator(gt2.end())
53 );
54 return gt1;
55 }
56
57 Eigen::MatrixXd lowRankPenaltyRows() const
58 {
59 if(!op2->field().sameField(field()))
60 {
61 throw std::runtime_error("Cannot combine different FEM fields.");
62 }
63 const auto a=lowRankBilinearRows(*op1);
64 const auto b=lowRankBilinearRows(*op2);
65 Eigen::MatrixXd result(a.rows()+b.rows(),field().gSize());
66 result.topRows(a.rows())=a;
67 result.bottomRows(b.rows())=b;
68 return result;
69 }
70
71 const auto& field() const
72 {
73 return op1->field();
74 }
75
76 };
77
78 template<class T1,class T2, std::enable_if_t<std::is_base_of_v<BilinearWeakExpression<T1>,T1> && std::is_base_of_v<BilinearWeakExpression<T2>,T2>,int> = 0>
79 auto operator+(const std::shared_ptr<T1>& x,const std::shared_ptr<T2>& y)
80 {
81 return std::make_shared<BilinearWeakSum<T1,T2>>(x,y);
82 }
83
84}
85#endif
a
Definition int_R.m:14
b
Definition int_R.m:16
x
Definition int_R.m:12
Eigen::MatrixXd lowRankBilinearRows(const Form &form)
auto operator+(const std::shared_ptr< T1 > &x, const std::shared_ptr< T2 > &y)
T1::TrialFunctionType TrialFunctionType
const auto & field() const
Eigen::MatrixXd lowRankPenaltyRows() const
std::vector< Eigen::Triplet< double > > globalTriplets() const
BilinearWeakSum(std::shared_ptr< T1 > x, std::shared_ptr< T2 > y)
const std::shared_ptr< T1 > op1
const std::shared_ptr< T2 > op2
result