1 // Gmsh - Copyright (C) 1997-2021 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 //
6 // Contributor(s):
7 // Eric Bechet
8 //
9
10 #ifndef SOLVERALGORITHMS_H
11 #define SOLVERALGORITHMS_H
12
13 #include "dofManager.h"
14 #include "terms.h"
15 #include "quadratureRules.h"
16 #include "MVertex.h"
17
18 template <class Iterator, class Assembler>
Assemble(BilinearTermBase & term,FunctionSpaceBase & space,Iterator itbegin,Iterator itend,QuadratureBase & integrator,Assembler & assembler)19 void Assemble(BilinearTermBase &term, FunctionSpaceBase &space,
20 Iterator itbegin, Iterator itend, QuadratureBase &integrator,
21 Assembler &assembler)
22 // symmetric
23 {
24 fullMatrix<typename Assembler::dataMat> localMatrix;
25 std::vector<Dof> R;
26 for(Iterator it = itbegin; it != itend; ++it) {
27 MElement *e = *it;
28 R.clear();
29 IntPt *GP;
30 int npts = integrator.getIntPoints(e, &GP);
31 term.get(e, npts, GP, localMatrix); // localMatrix.print();
32 space.getKeys(e, R);
33 assembler.assemble(R, localMatrix);
34 }
35 }
36
37 template <class Iterator, class Assembler>
Assemble(BilinearTermBase & term,FunctionSpaceBase & space,Iterator itbegin,Iterator itend,QuadratureBase & integrator,Assembler & assembler,elementFilter & efilter)38 void Assemble(BilinearTermBase &term, FunctionSpaceBase &space,
39 Iterator itbegin, Iterator itend, QuadratureBase &integrator,
40 Assembler &assembler, elementFilter &efilter)
41 // symmetric
42 {
43 fullMatrix<typename Assembler::dataMat> localMatrix;
44 std::vector<Dof> R;
45 for(Iterator it = itbegin; it != itend; ++it) {
46 MElement *e = *it;
47 if(efilter(e)) {
48 R.clear();
49 IntPt *GP;
50 int npts = integrator.getIntPoints(e, &GP);
51 term.get(e, npts, GP, localMatrix); // localMatrix.print();
52 space.getKeys(e, R);
53 assembler.assemble(R, localMatrix);
54 }
55 }
56 }
57
58 template <class Assembler>
Assemble(BilinearTermBase & term,FunctionSpaceBase & space,MElement * e,QuadratureBase & integrator,Assembler & assembler)59 void Assemble(BilinearTermBase &term, FunctionSpaceBase &space, MElement *e,
60 QuadratureBase &integrator, Assembler &assembler) // symmetric
61 {
62 fullMatrix<typename Assembler::dataMat> localMatrix;
63 std::vector<Dof> R;
64 IntPt *GP;
65 int npts = integrator.getIntPoints(e, &GP);
66 term.get(e, npts, GP, localMatrix);
67 space.getKeys(e, R);
68 assembler.assemble(R, localMatrix);
69 }
70
71 template <class Iterator, class Assembler>
Assemble(BilinearTermBase & term,FunctionSpaceBase & shapeFcts,FunctionSpaceBase & testFcts,Iterator itbegin,Iterator itend,QuadratureBase & integrator,Assembler & assembler)72 void Assemble(BilinearTermBase &term, FunctionSpaceBase &shapeFcts,
73 FunctionSpaceBase &testFcts, Iterator itbegin, Iterator itend,
74 QuadratureBase &integrator,
75 Assembler &assembler) // non symmetric
76 {
77 fullMatrix<typename Assembler::dataMat> localMatrix;
78 std::vector<Dof> R;
79 std::vector<Dof> C;
80 for(Iterator it = itbegin; it != itend; ++it) {
81 MElement *e = *it;
82 R.clear();
83 C.clear();
84 IntPt *GP;
85 int npts = integrator.getIntPoints(e, &GP);
86 term.get(e, npts, GP, localMatrix); // localMatrix.print();
87 // printf("local matrix size = %d %d\n", localMatrix.size1(),
88 // localMatrix.size2());
89 shapeFcts.getKeys(e, R);
90 testFcts.getKeys(e, C);
91 // std::cout << "assembling normal test function ; lagrange trial
92 // function : " << std::endl; for (int i = 0 ; i < R.size() ; i++)
93 // {
94 // std::cout << "tests : " << R[i].getEntity() << ":" << R[i].getType()
95 // << std::endl ;
96 // }
97 // for (int i = 0 ; i < R.size() ; i++)
98 // {
99 // std::cout << "trial : " << C[i].getEntity() << ":" << C[i].getType()
100 // << std::endl ;
101 // }
102 assembler.assemble(R, C, localMatrix);
103 // std::cout << "assembling lagrange test function ; normal trial
104 // function : " << std::endl; for (int i = 0 ; i < R.size() ; i++)
105 // {
106 // std::cout << "tests : " << C[i].getEntity() << ":" << C[i].getType()
107 // << std::endl ;
108 // }
109 // for (int i = 0 ; i < R.size() ; i++)
110 // {
111 // std::cout << "trial : " << R[i].getEntity() << ":" << R[i].getType()
112 // << std::endl ;
113 // }
114 assembler.assemble(C, R, localMatrix.transpose());
115 }
116 }
117
118 template <class Iterator, class Assembler>
Assemble(LinearTermBase<double> & term,FunctionSpaceBase & space,Iterator itbegin,Iterator itend,QuadratureBase & integrator,Assembler & assembler)119 void Assemble(LinearTermBase<double> &term, FunctionSpaceBase &space,
120 Iterator itbegin, Iterator itend, QuadratureBase &integrator,
121 Assembler &assembler)
122 {
123 fullVector<typename Assembler::dataMat> localVector;
124 std::vector<Dof> R;
125 for(Iterator it = itbegin; it != itend; ++it) {
126 MElement *e = *it;
127 R.clear();
128 IntPt *GP;
129 int npts = integrator.getIntPoints(e, &GP);
130 term.get(e, npts, GP, localVector); // localVector.print();
131 space.getKeys(e, R);
132 assembler.assemble(R, localVector);
133 }
134 }
135
136 template <class Iterator, class Assembler>
Assemble(LinearTermBase<double> & term,FunctionSpaceBase & space,Iterator itbegin,Iterator itend,QuadratureBase & integrator,Assembler & assembler,elementFilter & efilter)137 void Assemble(LinearTermBase<double> &term, FunctionSpaceBase &space,
138 Iterator itbegin, Iterator itend, QuadratureBase &integrator,
139 Assembler &assembler, elementFilter &efilter)
140 {
141 fullVector<typename Assembler::dataMat> localVector;
142 std::vector<Dof> R;
143 for(Iterator it = itbegin; it != itend; ++it) {
144 MElement *e = *it;
145 if(efilter(e)) {
146 R.clear();
147 IntPt *GP;
148 int npts = integrator.getIntPoints(e, &GP);
149 term.get(e, npts, GP, localVector); // localVector.print();
150 space.getKeys(e, R);
151 assembler.assemble(R, localVector);
152 }
153 }
154 }
155
156 template <class Assembler>
Assemble(LinearTermBase<double> & term,FunctionSpaceBase & space,MElement * e,QuadratureBase & integrator,Assembler & assembler)157 void Assemble(LinearTermBase<double> &term, FunctionSpaceBase &space,
158 MElement *e, QuadratureBase &integrator, Assembler &assembler)
159 {
160 fullVector<typename Assembler::dataMat> localVector;
161 std::vector<Dof> R;
162 IntPt *GP;
163 int npts = integrator.getIntPoints(e, &GP);
164 term.get(e, npts, GP, localVector);
165 space.getKeys(e, R);
166 assembler.assemble(R, localVector);
167 }
168
169 template <class Iterator, class dataMat>
Assemble(ScalarTermBase<double> & term,Iterator itbegin,Iterator itend,QuadratureBase & integrator,dataMat & val)170 void Assemble(ScalarTermBase<double> &term, Iterator itbegin, Iterator itend,
171 QuadratureBase &integrator, dataMat &val)
172 {
173 dataMat localval;
174 for(Iterator it = itbegin; it != itend; ++it) {
175 MElement *e = *it;
176 IntPt *GP;
177 int npts = integrator.getIntPoints(e, &GP);
178 term.get(e, npts, GP, localval);
179 val += localval;
180 }
181 }
182
183 template <class Iterator, class dataMat>
Assemble(ScalarTermBase<double> & term,Iterator itbegin,Iterator itend,QuadratureBase & integrator,dataMat & val,elementFilter & efilter)184 void Assemble(ScalarTermBase<double> &term, Iterator itbegin, Iterator itend,
185 QuadratureBase &integrator, dataMat &val, elementFilter &efilter)
186 {
187 dataMat localval;
188 for(Iterator it = itbegin; it != itend; ++it) {
189 MElement *e = *it;
190 if(efilter(e)) {
191 IntPt *GP;
192 int npts = integrator.getIntPoints(e, &GP);
193 term.get(e, npts, GP, localval);
194 val += localval;
195 }
196 }
197 }
198
199 template <class Iterator, class dataMat>
Assemble(ScalarTermBase<double> & term,MElement * e,QuadratureBase & integrator,dataMat & val)200 void Assemble(ScalarTermBase<double> &term, MElement *e,
201 QuadratureBase &integrator, dataMat &val)
202 {
203 dataMat localval;
204 IntPt *GP;
205 int npts = integrator.getIntPoints(e, &GP);
206 term.get(e, npts, GP, localval);
207 val += localval;
208 }
209
210 template <class Assembler>
FixDofs(Assembler & assembler,std::vector<Dof> & dofs,std::vector<typename Assembler::dataVec> & vals)211 void FixDofs(Assembler &assembler, std::vector<Dof> &dofs,
212 std::vector<typename Assembler::dataVec> &vals)
213 {
214 int nbff = dofs.size();
215 for(int i = 0; i < nbff; ++i) {
216 assembler.fixDof(dofs[i], vals[i]);
217 }
218 }
219
220 class FilterDof {
221 public:
~FilterDof()222 virtual ~FilterDof() {}
223 virtual bool operator()(Dof key) = 0;
224 };
225
226 class FilterDofTrivial : public FilterDof {
227 public:
operator()228 virtual bool operator()(Dof key) { return true; }
229 };
230
231 class FilterDofComponent : public FilterDof {
232 int comp;
233
234 public:
FilterDofComponent(int comp_)235 FilterDofComponent(int comp_) : comp(comp_) {}
operator()236 virtual bool operator()(Dof key)
237 {
238 int type = key.getType();
239 int icomp, iphys;
240 Dof::getTwoIntsFromType(type, icomp, iphys);
241 if(icomp == comp) return true;
242 return false;
243 }
244 };
245
246 // return true if the Dof is in a filled set
247 class FilterDofSet : public FilterDof {
248 protected:
249 std::set<Dof> _dofset;
250
251 public:
FilterDofSet()252 FilterDofSet() : FilterDof() {}
~FilterDofSet()253 virtual ~FilterDofSet() {}
operator()254 virtual bool operator()(Dof key)
255 {
256 auto itR = _dofset.find(key);
257 if(itR == _dofset.end()) {
258 return false;
259 }
260 return true;
261 }
addDof(Dof key)262 virtual void addDof(Dof key) { _dofset.insert(key); }
addDof(std::vector<Dof> & R)263 virtual void addDof(std::vector<Dof> &R)
264 {
265 for(std::size_t i = 0; i < R.size(); i++) this->addDof(R[i]);
266 }
267 };
268
269 template <class Assembler>
FixNodalDofs(FunctionSpaceBase & space,MElement * e,Assembler & assembler,simpleFunction<typename Assembler::dataVec> & fct,FilterDof & filter)270 void FixNodalDofs(FunctionSpaceBase &space, MElement *e, Assembler &assembler,
271 simpleFunction<typename Assembler::dataVec> &fct,
272 FilterDof &filter)
273 {
274 std::vector<MVertex *> tabV;
275 int nv = e->getNumVertices();
276 std::vector<Dof> R;
277 space.getKeys(e, R);
278 tabV.reserve(nv);
279 for(int i = 0; i < nv; ++i) tabV.push_back(e->getVertex(i));
280
281 for(auto itd = R.begin(); itd != R.end(); ++itd) {
282 Dof key = *itd;
283 if(filter(key)) {
284 for(int i = 0; i < nv; ++i) {
285 if((long int)tabV[i]->getNum() == key.getEntity()) {
286 assembler.fixDof(key, fct(tabV[i]->x(), tabV[i]->y(), tabV[i]->z()));
287 break;
288 }
289 }
290 }
291 }
292 }
293
294 template <class Iterator, class Assembler>
FixNodalDofs(FunctionSpaceBase & space,Iterator itbegin,Iterator itend,Assembler & assembler,simpleFunction<typename Assembler::dataVec> & fct,FilterDof & filter)295 void FixNodalDofs(FunctionSpaceBase &space, Iterator itbegin, Iterator itend,
296 Assembler &assembler,
297 simpleFunction<typename Assembler::dataVec> &fct,
298 FilterDof &filter)
299 {
300 for(Iterator it = itbegin; it != itend; ++it)
301 FixNodalDofs(space, *it, assembler, fct, filter);
302 }
303
304 template <class Iterator, class Assembler>
FixVoidNodalDofs(FunctionSpaceBase & space,Iterator itbegin,Iterator itend,Assembler & assembler)305 void FixVoidNodalDofs(FunctionSpaceBase &space, Iterator itbegin,
306 Iterator itend, Assembler &assembler)
307 {
308 FilterDofTrivial filter;
309 simpleFunction<typename Assembler::dataVec> fct(0.);
310 FixNodalDofs(space, itbegin, itend, assembler, fct, filter);
311 }
312
313 template <class Iterator, class Assembler>
NumberDofs(FunctionSpaceBase & space,Iterator itbegin,Iterator itend,Assembler & assembler)314 void NumberDofs(FunctionSpaceBase &space, Iterator itbegin, Iterator itend,
315 Assembler &assembler)
316 {
317 for(Iterator it = itbegin; it != itend; ++it) {
318 MElement *e = *it;
319 std::vector<Dof> R;
320 space.getKeys(e, R);
321 int nbdofs = R.size();
322 for(int i = 0; i < nbdofs; ++i) assembler.numberDof(R[i]);
323 }
324 }
325
326 //// Mean HangingNodes
327 // template <class Assembler> void FillHangingNodes(FunctionSpaceBase &space,
328 // std::map<int,std::vector <int> > &HangingNodes, Assembler &assembler, int
329 // &field, int &dim)
330 //{
331 // std::map<int, std::vector <int> >::iterator ith;
332 // ith = HangingNodes.begin();
333 // int compt = 1;
334 // while (ith != HangingNodes.end()){
335 // float fac;
336 // fac = 1.0 / (ith->second).size();
337 // for (int j = 0; j < dim; j++){
338 // DofAffineConstraint<double> constraint;
339 // int type = Dof::createTypeWithTwoInts(j, field);
340 // Dof hgnd(ith->first, type);
341 // for (int i = 0; i < (ith->second).size(); i++){
342 // Dof key((ith->second)[i], type);
343 // std::pair<Dof, double > linDof(key, fac);
344 // constraint.linear.push_back(linDof);
345 // }
346 // constraint.shift = 0;
347 // assembler.setLinearConstraint (hgnd, constraint);
348 // }
349 // ith++;
350 // compt++;
351 // }
352 //}
353
354 #endif
355