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