Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
AssembleFENonLinLaplace_def.hpp
1#ifndef ASSEMBLEFENONLINLAPLACE_DEF_hpp
2#define ASSEMBLEFENONLINLAPLACE_DEF_hpp
3
4#include "AssembleFENonLinLaplace_decl.hpp"
5#include "feddlib/core/FEDDCore.hpp"
6#include <Teuchos_Array.hpp>
7#include <Teuchos_ScalarTraitsDecl.hpp>
8#include <cmath>
9
10namespace FEDD {
11
12void rhsFunc(double *x, double *res, double *parameters) {
13 res[0] = 1; // x[0] * sin(x[1]);
14}
15
24template <class SC, class LO, class GO, class NO>
26 int flag, vec2D_dbl_Type nodesRefConfig, ParameterListPtr_Type params,
27 tuple_disk_vec_ptr_Type tuple)
28 : AssembleFE<SC, LO, GO, NO>(flag, nodesRefConfig, params, tuple) {
29
30 this->FEType_ = std::get<1>(this->diskTuple_->at(0));
31 this->dofs_ = std::get<2>(this->diskTuple_->at(0));
32 // Same as this->getNodesRefConfig().size();
33 this->numNodes_ = std::get<3>(this->diskTuple_->at(0));
34 this->dofsElement_ = this->numNodes_ * this->dofs_;
35 // Specifying rhs func here for now
36 // Should be done in main when possible
37 this->rhsFunc_ = rhsFunc;
38}
39
44
45template <class SC, class LO, class GO, class NO>
47
48 SmallMatrixPtr_Type elementMatrix =
49 Teuchos::rcp(new SmallMatrix_Type(this->dofsElement_));
50 assemblyNonLinLaplacian(elementMatrix);
51
52 this->jacobian_ = elementMatrix;
53}
54
61template <class SC, class LO, class GO, class NO>
62void AssembleFENonLinLaplace<SC, LO, GO, NO>::assemblyNonLinLaplacian(
63 SmallMatrixPtr_Type &elementMatrix) {
64
65 int dim = this->getDim();
66 UN deg = 2*Helper::determineDegree(dim, this->FEType_,Helper::Deriv1); // TODO: [JK] 2025/04 Please check if degree is really sufficient. What about u_0^2?
67
68 vec3D_dbl_ptr_Type dPhi;
69 vec2D_dbl_ptr_Type phi;
70 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
71
72 // Get values of nodal basis at the quadrature nodes
73 Helper::getDPhi(dPhi, weights, dim, this->FEType_, deg);
74 Helper::getPhi(phi, weights, dim, this->FEType_, deg);
75
76 // Built affine transformation from the reference element to the current
77 // element
78 SC detB;
79 SC absDetB;
80 SmallMatrix<SC> B(dim);
81 SmallMatrix<SC> Binv(dim);
82 buildTransformation(B);
83 detB = B.computeInverse(Binv);
84 absDetB = std::fabs(detB);
85 vec3D_dbl_Type dPhiTrans(
86 dPhi->size(),
87 vec2D_dbl_Type(dPhi->at(0).size(), vec_dbl_Type(dim, 0.)));
88 // Apple transformation to gradients of basis functions
89 applyBTinv(dPhi, dPhiTrans, Binv);
90
91 vec_dbl_Type uLoc(weights->size(), 0.);
92 // At each quad node p_i gradient vector is duLoc[w] = [\partial_x phi,
93 // \partial_y phi]
94 vec2D_dbl_Type duLoc(weights->size(), vec_dbl_Type(dim, 0));
95
96 // Build vector of current solution at quadrature nodes
97 // Iterate over quadrature nodes
98 for (int w = 0; w < phi->size(); w++) {
99 // Iterate over each basis function at the current quadrature node
100 for (int i = 0; i < phi->at(0).size(); i++) {
101 uLoc[w] += (*this->solution_)[i] * phi->at(w).at(i);
102 for (int d = 0; d < dim; d++) {
103 duLoc[w][d] += (*this->solution_)[i] * dPhiTrans[w][i][d];
104 }
105 }
106 }
107
108 // Build local stiffness matrix
109 auto value = Teuchos::ScalarTraits<SC>::zero();
110 for (UN i = 0; i < this->numNodes_; i++) {
111 for (UN j = 0; j < this->numNodes_; j++) {
112 value = 0.;
113 for (UN w = 0; w < weights->size(); w++) {
114 for (UN d = 0; d < dim; d++) {
115 value += weights->at(w) *
116 ((1 + uLoc[w] * uLoc[w]) * dPhiTrans[w][i][d] +
117 2 * uLoc[w] * phi->at(w).at(j) * duLoc[w][d]) *
118 dPhiTrans[w][j][d];
119 }
120 }
121 value *= absDetB;
122 (*elementMatrix)[i][j] = value;
123 }
124 }
125}
126
133template <class SC, class LO, class GO, class NO>
135
136 int dim = this->getDim();
137 UN deg = 2*Helper::determineDegree(dim, this->FEType_, Helper::Deriv1); // TODO: [JK] 2025/04 Please check if degree is really sufficient. What about u_0^2?
138
139 vec3D_dbl_ptr_Type dPhi;
140 vec2D_dbl_ptr_Type phi;
141 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
142
143 Helper::getDPhi(dPhi, weights, dim, this->FEType_, deg);
144 Helper::getPhi(phi, weights, dim, this->FEType_, deg);
145
146 SC detB;
147 SC absDetB;
148 SmallMatrix<SC> B(dim);
149 SmallMatrix<SC> Binv(dim);
150 buildTransformation(B);
151 detB = B.computeInverse(Binv);
152 absDetB = std::fabs(detB);
153 vec3D_dbl_Type dPhiTrans(
154 weights->size(),
155 vec2D_dbl_Type(dPhi->at(0).size(), vec_dbl_Type(dim, 0.)));
156 applyBTinv(dPhi, dPhiTrans, Binv);
157 vec_dbl_Type uLoc(weights->size(), 0.);
158 vec_dbl_ptr_Type funcValues;
159 Helper::getFuncAtQuadNodes(funcValues, this->rhsFunc_, dim, this->FEType_,
160 deg);
161
162 // Build vector of current solution at quadrature nodes
163 for (int w = 0; w < phi->size(); w++) { // quadrature nodes
164 for (int i = 0; i < phi->at(0).size();
165 i++) { // each basis function at the current quadrature node
166 uLoc[w] += (*this->solution_)[i] * phi->at(w).at(i);
167 }
168 }
169
170 this->rhsVec_.reset(new vec_dbl_Type(this->dofsElement_, 0.));
171 // $fv$ term
172 auto valueOne = Teuchos::ScalarTraits<SC>::zero();
173 // $(1 + u_0^2)\nabla u_0 \nabla v$ term
174 auto valueTwo = Teuchos::ScalarTraits<SC>::zero();
175 // for storing matrix_column \cdot current_solution reduction operation
176 auto reductionValue = Teuchos::ScalarTraits<SC>::zero();
177 // Build local stiffness matrx
178 for (UN i = 0; i < this->numNodes_; i++) {
179 reductionValue = 0.;
180 // Iterate test functions (rows)
181 for (UN j = 0; j < this->numNodes_; j++) {
182 valueTwo = 0.;
183 // Iterate quadrature nodes
184 for (UN w = 0; w < dPhiTrans.size(); w++) {
185 for (UN d = 0; d < dim; d++) {
186 valueTwo += weights->at(w) * (1 + uLoc[w] * uLoc[w]) *
187 dPhiTrans[w][i][d] * dPhiTrans[w][j][d];
188 }
189 }
190 // Perform reduction of current valueTwo and solution
191 reductionValue += valueTwo * (*this->solution_)[j];
192 }
193 reductionValue *= absDetB;
194 valueOne = 0.;
195 for (UN w = 0; w < dPhiTrans.size(); w++) {
196 // Note that phi does not require transformation. absDetB suffices.
197 valueOne += weights->at(w) * funcValues->at(w) * phi->at(w).at(i);
198 }
199 valueOne *= absDetB;
200 (*this->rhsVec_)[i] = -(valueOne - reductionValue);
201 }
202}
203
208
209template <class SC, class LO, class GO, class NO>
210void AssembleFENonLinLaplace<SC, LO, GO, NO>::buildTransformation(
211 SmallMatrix<SC> &B) {
212
213 TEUCHOS_TEST_FOR_EXCEPTION((B.size() < 2 || B.size() > 3), std::logic_error,
214 "Initialize SmallMatrix for transformation.");
215 UN index;
216 UN index0 = 0;
217 for (UN j = 0; j < B.size(); j++) {
218 index = j + 1;
219 for (UN i = 0; i < B.size(); i++) {
220 // name nodesRefConfig_ is deceptive: actually holds coords of nodes
221 // of current element
222 B[i][j] = this->nodesRefConfig_.at(index).at(i) -
223 this->nodesRefConfig_.at(index0).at(i);
224 }
225 }
226}
227
234template <class SC, class LO, class GO, class NO>
235void AssembleFENonLinLaplace<SC, LO, GO, NO>::applyBTinv(
236 vec3D_dbl_ptr_Type &dPhiIn, vec3D_dbl_Type &dPhiOut,
237 SmallMatrix<SC> &Binv) {
238 UN dim = Binv.size();
239 for (UN w = 0; w < dPhiIn->size(); w++) {
240 for (UN i = 0; i < dPhiIn->at(w).size(); i++) {
241 for (UN d1 = 0; d1 < dim; d1++) {
242 for (UN d2 = 0; d2 < dim; d2++) {
243 dPhiOut[w][i][d1] +=
244 dPhiIn->at(w).at(i).at(d2) * Binv[d2][d1];
245 }
246 }
247 }
248 }
249}
250
251} // namespace FEDD
252#endif
void assembleRHS() override
Assemble the element right hand side vector.
Definition AssembleFENonLinLaplace_def.hpp:134
void assembleJacobian() override
Assemble the element Jacobian matrix.
Definition AssembleFENonLinLaplace_def.hpp:46
AssembleFENonLinLaplace(int flag, vec2D_dbl_Type nodesRefConfig, ParameterListPtr_Type parameters, tuple_disk_vec_ptr_Type tuple)
Constructor for AssembleFENonLinLaplace.
Definition AssembleFENonLinLaplace_def.hpp:25
AssembleFE(int flag, vec2D_dbl_Type nodesRefConfig, ParameterListPtr_Type parameters, tuple_disk_vec_ptr_Type tuple)
Definition AssembleFE_def.hpp:10
static UN determineDegree(UN dim, std::string FEType, VarType orderOfDerivative)
Determine polynomial degree of a finite element basis function or its gradient that is required to se...
Definition Helper.cpp:68
@ Deriv1
order 1, gradient(f(x))
Definition Helper.hpp:28
static int getPhi(vec2D_dbl_ptr_Type &Phi, vec_dbl_ptr_Type &weightsPhi, int dim, std::string FEType, int Degree, std::string FETypeQuadPoints="")
Get basisfunction phi per quadrature point.
Definition Helper.cpp:604
static int getDPhi(vec3D_dbl_ptr_Type &DPhi, vec_dbl_ptr_Type &weightsDPhi, int Dimension, std::string FEType, int Degree)
Full matrix representation of gradient of a basis function for each quadrature point.
Definition Helper.cpp:215
This class represents a templated small Matrix of type T. Primarily created for 2x2 and 3x3 matrices....
Definition SmallMatrix.hpp:22
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5