v0.14.0
Loading...
Searching...
No Matches
nonlinear_poisson_2d.hpp
Go to the documentation of this file.
1#ifndef __NONLINEARPOISSON2D_HPP__
2#define __NONLINEARPOISSON2D_HPP__
3
4#include <stdlib.h>
5#include <MoFEM.hpp>
6using namespace MoFEM;
7
9using DomainEleOp = DomainEle::UserDataOperator;
13
14
21
22
27
28
30
32
34
35typedef boost::function<double(const double, const double, const double)>
37
38
40public:
42 std::string row_field_name, std::string col_field_name,
43 boost::shared_ptr<VectorDouble> field_vec,
44 boost::shared_ptr<MatrixDouble> field_grad_mat)
45 : AssemblyDomainEleOp(row_field_name, col_field_name,
46 DomainEleOp::OPROWCOL),
47 fieldVec(field_vec), fieldGradMat(field_grad_mat) {}
48
50 EntData &col_data) {
52
53 auto &locLhs = AssemblyDomainEleOp::locMat;
54
55 const int nb_row_dofs = row_data.getIndices().size();
56 const int nb_col_dofs = col_data.getIndices().size();
57 // get element area
58 const double area = getMeasure();
59
60 // get number of integration points
61 const int nb_integration_points = getGaussPts().size2();
62 // get integration weights
63 auto t_w = getFTensor0IntegrationWeight();
64 // get solution (field value) at integration points
65 auto t_field = getFTensor0FromVec(*fieldVec);
66 // get gradient of field at integration points
67 auto t_field_grad = getFTensor1FromMat<2>(*fieldGradMat);
68
69 // get base functions on row
70 auto t_row_base = row_data.getFTensor0N();
71 // get derivatives of base functions on row
72 auto t_row_diff_base = row_data.getFTensor1DiffN<2>();
73
74 // START THE LOOP OVER INTEGRATION POINTS TO CALCULATE LOCAL MATRIX
75 for (int gg = 0; gg != nb_integration_points; gg++) {
76 const double a = t_w * area;
77
78 for (int rr = 0; rr != nb_row_dofs; ++rr) {
79 // get base functions on column
80 auto t_col_base = col_data.getFTensor0N(gg, 0);
81 // get derivatives of base functions on column
82 auto t_col_diff_base = col_data.getFTensor1DiffN<2>(gg, 0);
83
84 for (int cc = 0; cc != nb_col_dofs; cc++) {
85 locLhs(rr, cc) += (((1 + t_field * t_field) * t_row_diff_base(i) *
86 t_col_diff_base(i)) +
87 (2.0 * t_field * t_field_grad(i) *
88 t_row_diff_base(i) * t_col_base)) *
89 a;
90
91 // move to the next base functions on column
92 ++t_col_base;
93 // move to the derivatives of the next base function on column
94 ++t_col_diff_base;
95 }
96
97 // move to the next base function on row
98 ++t_row_base;
99 // move to the derivatives of the next base function on row
100 ++t_row_diff_base;
101 }
102
103 // move to the weight of the next integration point
104 ++t_w;
105 // move to the solution (field value) at the next integration point
106 ++t_field;
107 // move to the gradient of field value at the next integration point
108 ++t_field_grad;
109 }
110
112 }
113
114private:
115 boost::shared_ptr<VectorDouble> fieldVec;
116 boost::shared_ptr<MatrixDouble> fieldGradMat;
117};
118
120public:
122 std::string field_name, ScalarFunc source_term_function,
123 boost::shared_ptr<VectorDouble> field_vec,
124 boost::shared_ptr<MatrixDouble> field_grad_mat)
126 sourceTermFunc(source_term_function), fieldVec(field_vec),
127 fieldGradMat(field_grad_mat) {}
128
131
132 auto &nf = AssemblyDomainEleOp::locF;
133
134
135 // get element area
136 const double area = getMeasure();
137
138 // get number of integration points
139 const int nb_integration_points = getGaussPts().size2();
140 // get integration weights
141 auto t_w = getFTensor0IntegrationWeight();
142 // get coordinates of the integration point
143 auto t_coords = getFTensor1CoordsAtGaussPts();
144 // get solution (field value) at integration point
145 auto t_field = getFTensor0FromVec(*fieldVec);
146 // get gradient of field value of integration point
147 auto t_field_grad = getFTensor1FromMat<2>(*fieldGradMat);
148
149 // get base function
150 auto t_base = data.getFTensor0N();
151 // get derivatives of base function
152 auto t_grad_base = data.getFTensor1DiffN<2>();
153
154 // START THE LOOP OVER INTEGRATION POINTS TO CALCULATE LOCAL VECTOR
155 for (int gg = 0; gg != nb_integration_points; gg++) {
156 const double a = t_w * area;
157 double body_source =
158 sourceTermFunc(t_coords(0), t_coords(1), t_coords(2));
159
160 // calculate the local vector
161 for (int rr = 0; rr != AssemblyDomainEleOp::nbRows; rr++) {
162 nf[rr] +=
163 (-t_base * body_source +
164 t_grad_base(i) * t_field_grad(i) * (1 + t_field * t_field)) *
165 a;
166
167 // move to the next base function
168 ++t_base;
169 // move to the derivatives of the next base function
170 ++t_grad_base;
171 }
172
173 // move to the weight of the next integration point
174 ++t_w;
175 // move to the coordinates of the next integration point
176 ++t_coords;
177 // move to the solution (field value) at the next integration point
178 ++t_field;
179 // move to the gradient of field value at the next integration point
180 ++t_field_grad;
181
182 }
183
185 }
186
187private:
189 boost::shared_ptr<VectorDouble> fieldVec;
190 boost::shared_ptr<MatrixDouble> fieldGradMat;
191
192};
193
194}; // namespace NonlinearPoissonOps
195
196#endif //__NONLINEARPOISSON2D_HPP__
constexpr double a
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
[Define dimension]
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
FTensor::Tensor1< FTensor::PackPtr< T *, S >, Tensor_Dim > getFTensor1FromMat(ublas::matrix< T, L, A > &data)
Get tensor rank 1 (vector) form data matrix.
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
FTensor::Index< 'i', 2 > i
boost::function< double(const double, const double, const double)> ScalarFunc
FormsIntegrators< BoundaryEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< 1, 1 > OpBoundaryRhsSource
FormsIntegrators< BoundaryEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpBoundaryRhs
FormsIntegrators< BoundaryEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, 1 > OpBoundaryLhs
constexpr auto field_name
OpBaseImpl< PETSC, EdgeEleOp > OpBase
Definition radiation.cpp:29
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
const VectorInt & getIndices() const
Get global indices of dofs on entity.
MoFEM::FaceElementForcesAndSourcesCore FaceEle
MoFEM::EdgeElementForcesAndSourcesCore EdgeEle
boost::shared_ptr< VectorDouble > fieldVec
boost::shared_ptr< MatrixDouble > fieldGradMat
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data)
OpDomainLhs(std::string row_field_name, std::string col_field_name, boost::shared_ptr< VectorDouble > field_vec, boost::shared_ptr< MatrixDouble > field_grad_mat)
boost::shared_ptr< VectorDouble > fieldVec
MoFEMErrorCode iNtegrate(EntData &data)
OpDomainRhs(std::string field_name, ScalarFunc source_term_function, boost::shared_ptr< VectorDouble > field_vec, boost::shared_ptr< MatrixDouble > field_grad_mat)
boost::shared_ptr< MatrixDouble > fieldGradMat
FormsIntegrators< BoundaryEleOp >::Assembly< A >::OpBase AssemblyBoundaryEleOp
FormsIntegrators< DomainEleOp >::Assembly< A >::OpBase AssemblyDomainEleOp