gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
thermicSolver.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 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 #include <string.h>
7 #include "GmshConfig.h"
8 #include "thermicSolver.h"
9 #include "linearSystemCSR.h"
10 #include "linearSystemPETSc.h"
11 #include "linearSystemFull.h"
12 #include "Numeric.h"
13 #include "GModel.h"
14 #include "functionSpace.h"
15 #include "terms.h"
16 #include "solverAlgorithms.h"
17 #include "quadratureRules.h"
18 #include "solverField.h"
19 #include "MPoint.h"
20 #include "gmshLevelset.h"
21 
22 #if defined(HAVE_POST)
23 #include "PView.h"
24 #include "PViewData.h"
25 #endif
26 
27 void thermicSolver::setMesh(const std::string &meshFileName)
28 {
29  pModel = new GModel();
30  pModel->readMSH(meshFileName.c_str());
31  _dim = pModel->getNumRegions() ? 3 : 2;
32 
33  if(LagSpace) delete LagSpace;
35 
38 }
39 
41 {
42 #if defined(HAVE_PETSC)
44 #elif defined(HAVE_GMM)
46  lsys->setGmres(1);
47  lsys->setNoisy(1);
48 #else
50 #endif
51  assemble(lsys);
52  lsys->systemSolve();
53  printf("-- done solving!\n");
54 }
55 
57 {
59  pModel->writeMSH("cutMesh.msh");
60 }
61 
62 void thermicSolver::setThermicDomain(int phys, double k)
63 {
64  thermicField field;
65  field._k = k;
66  field._tag = _tag;
67  field.g = new groupOfElements(_dim, phys);
68  thermicFields.push_back(field);
69 }
70 
71 void thermicSolver::changeLMTau(int tag, double tau)
72 {
73  for(std::size_t i = 0; i < LagrangeMultiplierFields.size(); i++) {
74  if(LagrangeMultiplierFields[i]._tag == tag) {
75  LagrangeMultiplierFields[i]._tau = tau;
76  }
77  }
78 }
79 
80 void thermicSolver::setLagrangeMultipliers(int phys, double tau, int tag,
82 {
84  field._tau = tau;
85  field._tag = tag;
86  field._f = f;
87  field.g = new groupOfElements(_dim - 1, phys);
88  LagrangeMultiplierFields.push_back(field);
89 }
90 
92 {
93  dirichletBCT diri;
94  diri.g = new groupOfElements(1, edge);
95  diri._f = f;
96  diri._tag = edge;
98  allDirichlet.push_back(diri);
99 }
100 
102 {
103  dirichletBCT diri;
104  diri.g = new groupOfElements(2, face);
105  diri._f = f;
106  diri._tag = face;
108  allDirichlet.push_back(diri);
109 }
110 
112 {
113  if(pAssembler) delete pAssembler;
114  pAssembler = new dofManager<double>(lsys);
115 
116  // we first do all fixations. the behavior of the dofManager is to
117  // give priority to fixations : when a dof is fixed, it cannot be
118  // numbered afterwards
119 
120  // Dirichlet conditions
121  for(std::size_t i = 0; i < allDirichlet.size(); i++) {
122  FilterDofTrivial filter;
123  FixNodalDofs(*LagSpace, allDirichlet[i].g->begin(),
124  allDirichlet[i].g->end(), *pAssembler, *allDirichlet[i]._f,
125  filter);
126  }
127  // LagrangeMultipliers
128  for(std::size_t i = 0; i < LagrangeMultiplierFields.size(); ++i) {
130  LagrangeMultiplierFields[i].g->end(), *pAssembler);
131  }
132  // Thermic Fields
133  for(std::size_t i = 0; i < thermicFields.size(); ++i) {
134  NumberDofs(*LagSpace, thermicFields[i].g->begin(),
135  thermicFields[i].g->end(), *pAssembler);
136  }
137  // Neumann conditions
138  GaussQuadrature Integ_Boundary(GaussQuadrature::Val);
139  for(std::size_t i = 0; i < allNeumann.size(); i++) {
140  std::cout << "Neumann BC" << std::endl;
141  LoadTerm<double> Lterm(*LagSpace, allNeumann[i]._f);
142  Assemble(Lterm, *LagSpace, allNeumann[i].g->begin(), allNeumann[i].g->end(),
143  Integ_Boundary, *pAssembler);
144  }
145  // Assemble cross term, laplace term and rhs term for LM
146  GaussQuadrature Integ_LagrangeMult(GaussQuadrature::ValVal);
148  for(std::size_t i = 0; i < LagrangeMultiplierFields.size(); i++) {
149  printf("Lagrange Mult Lag\n");
151  1.);
153  LagrangeMultiplierFields[i].g->begin(),
154  LagrangeMultiplierFields[i].g->end(), Integ_LagrangeMult,
155  *pAssembler);
156  printf("Lagrange Mult Lap\n");
158  -LagrangeMultiplierFields[i]._tau);
160  LagrangeMultiplierFields[i].g->begin(),
161  LagrangeMultiplierFields[i].g->end(), Integ_Laplace, *pAssembler);
162  printf("Lagrange Mult Load\n");
166  LagrangeMultiplierFields[i].g->begin(),
167  LagrangeMultiplierFields[i].g->end(), Integ_Boundary, *pAssembler);
168  }
169  // Assemble thermic term
171  for(std::size_t i = 0; i < thermicFields.size(); i++) {
172  printf("Thermic Term\n");
174  Assemble(Tterm, *LagSpace, thermicFields[i].g->begin(),
175  thermicFields[i].g->end(), Integ_Bulk, *pAssembler);
176  }
177 
178  /*for (int i = 0;i<pAssembler->sizeOfR();i++){
179  for (int j = 0;j<pAssembler->sizeOfR();j++){
180  double d; lsys->getFromMatrix(i, j, d);
181  printf("%g ", d);
182  }
183  double d; lsys->getFromRightHandSide(i, d);
184  printf(" | %g\n", d);
185  }*/
186 
187  printf("nDofs=%d\n", pAssembler->sizeOfR());
188  printf("nFixed=%d\n", pAssembler->sizeOfF());
189 }
190 
192 {
193  double val = 0.0;
195  for(std::size_t i = 0; i < thermicFields.size(); ++i) {
196  for(auto it =
197  thermicFields[i].g->begin();
198  it != thermicFields[i].g->end(); ++it) {
199  MElement *e = *it;
200  // printf("element (%g,%g) (%g,%g)
201  // (%g,%g)\n",e->getVertex(0)->x(),e->getVertex(0)->y(),e->getVertex(1)->x(),e->getVertex(1)->y(),e->getVertex(2)->x(),e->getVertex(2)->y());
202  int npts;
203  IntPt *GP;
204  double jac[3][3];
205  int integrationOrder = 2 * (e->getPolynomialOrder() + 5);
206  e->getIntegrationPoints(integrationOrder, &npts, &GP);
207  for(int j = 0; j < npts; j++) {
208  double u = GP[j].pt[0];
209  double v = GP[j].pt[1];
210  double w = GP[j].pt[2];
211  double weight = GP[j].weight;
212  double detJ = fabs(e->getJacobian(u, v, w, jac));
213  SPoint3 p;
214  e->pnt(u, v, w, p);
215  double FEMVALUE;
216  solField.f(e, u, v, w, FEMVALUE);
217  double diff = (*sol)(p.x(), p.y(), p.z()) - FEMVALUE;
218  val += diff * diff * detJ * weight;
219  // printf("(%g %g) : detJ=%g we=%g FV=%g sol=%g
220  // diff=%g\n",p.x(),p.y(),detJ,weight,FEMVALUE,(*sol)(p.x(), p.y(),
221  // p.z()),diff);
222  }
223  }
224  }
225  printf("L2Norm = %g\n", sqrt(val));
226  return sqrt(val);
227 }
228 
230 {
231  double val = 0.0, val2 = 0.0;
233  for(std::size_t i = 0; i < LagrangeMultiplierFields.size(); ++i) {
234  if(tag != LagrangeMultiplierFields[i]._tag) continue;
235  for(auto it =
236  LagrangeMultiplierFields[i].g->begin();
237  it != LagrangeMultiplierFields[i].g->end(); ++it) {
238  MElement *e = *it;
239  // printf("element (%g,%g)
240  // (%g,%g)\n",e->getVertex(0)->x(),e->getVertex(0)->y(),e->getVertex(1)->x(),e->getVertex(1)->y());
241  int npts;
242  IntPt *GP;
243  double jac[3][3];
244  int integrationOrder = 2 * (e->getPolynomialOrder() + 1);
245  e->getIntegrationPoints(integrationOrder, &npts, &GP);
246  for(int j = 0; j < npts; j++) {
247  double u = GP[j].pt[0];
248  double v = GP[j].pt[1];
249  double w = GP[j].pt[2];
250  double weight = GP[j].weight;
251  double detJ = fabs(e->getJacobian(u, v, w, jac));
252  SPoint3 p;
253  e->getParent()->pnt(u, v, w, p);
254  double FEMVALUE;
255  solField.f(e, u, v, w, FEMVALUE);
256  double diff = (*sol)(p.x(), p.y(), p.z()) - FEMVALUE;
257  val += diff * diff * detJ * weight;
258  val2 += (*sol)(p.x(), p.y(), p.z()) * (*sol)(p.x(), p.y(), p.z()) *
259  detJ * weight;
260  // printf("(%g %g) : u,v=(%g,%g) detJ=%g we=%g FV=%g sol=%g
261  // diff=%g\n",p.x(),p.y(),u,v,detJ,weight,FEMVALUE,(*sol)(p.x(), p.y(),
262  // p.z()),diff);
263  }
264  }
265  }
266  printf("LagNorm = %g\n", sqrt(val / val2));
267  return sqrt(val / val2);
268 }
269 
270 #if defined(HAVE_POST)
271 
272 PView *thermicSolver::buildTemperatureView(const std::string postFileName)
273 {
274  std::cout << "build Temperature View" << std::endl;
275  std::set<MVertex *> v;
276  std::map<MVertex *, MElement *> vCut;
277  for(std::size_t i = 0; i < thermicFields.size(); ++i) {
278  for(auto it =
279  thermicFields[i].g->begin();
280  it != thermicFields[i].g->end(); ++it) {
281  MElement *e = *it;
282  if(e->getParent()) {
283  for(std::size_t j = 0; j < e->getNumVertices(); ++j) {
284  if(vCut.find(e->getVertex(j)) == vCut.end())
285  vCut[e->getVertex(j)] = e->getParent();
286  }
287  }
288  else {
289  for(std::size_t j = 0; j < e->getNumVertices(); ++j)
290  v.insert(e->getVertex(j));
291  }
292  }
293  }
294  std::map<int, std::vector<double> > data;
296  for(auto it = v.begin(); it != v.end(); ++it) {
297  double val;
298  MPoint p(*it);
299  Field.f(&p, 0, 0, 0, val); // printf("valv=%g\n",val);
300  std::vector<double> vec;
301  vec.push_back(val);
302  data[(*it)->getNum()] = vec;
303  }
304  for(auto it = vCut.begin();
305  it != vCut.end(); ++it) {
306  double val;
307  double uvw[3];
308  double xyz[3] = {it->first->x(), it->first->y(), it->first->z()};
309  it->second->xyz2uvw(xyz, uvw);
310  Field.f(it->second, uvw[0], uvw[1], uvw[2],
311  val); // printf("valvc=%g\n",val);
312  std::vector<double> vec;
313  vec.push_back(val);
314  data[it->first->getNum()] = vec;
315  }
316  PView *pv = new PView(postFileName, "NodeData", pModel, data, 0.0, 1);
317  return pv;
318 }
319 
320 PView *
321 thermicSolver::buildLagrangeMultiplierView(const std::string &postFileName)
322 {
323  std::cout << "build Lagrange Multiplier View" << std::endl;
324  if(!LagrangeMultiplierSpace) return new PView();
325  std::set<MVertex *> v;
326  for(std::size_t i = 0; i < LagrangeMultiplierFields.size(); ++i) {
327  for(auto it =
328  LagrangeMultiplierFields[i].g->begin();
329  it != LagrangeMultiplierFields[i].g->end(); ++it) {
330  MElement *e = *it;
331  for(std::size_t j = 0; j < e->getNumVertices(); ++j)
332  v.insert(e->getVertex(j));
333  }
334  }
335  std::map<int, std::vector<double> > data;
337  for(auto it = v.begin(); it != v.end(); ++it) {
338  double val;
339  MPoint p(*it);
340  Field.f(&p, 0, 0, 0, val);
341  std::vector<double> vec;
342  vec.push_back(val);
343  data[(*it)->getNum()] = vec;
344  }
345  PView *pv = new PView(postFileName, "NodeData", pModel, data, 0.0, 1);
346  return pv;
347 }
348 
349 PView *thermicSolver::buildErrorEstimateView(const std::string &errorFileName,
351 {
352  std::cout << "build Error View" << std::endl;
353  std::map<int, std::vector<double> > data;
354 
356  for(std::size_t i = 0; i < thermicFields.size(); ++i) {
357  for(auto it =
358  thermicFields[i].g->begin();
359  it != thermicFields[i].g->end(); ++it) {
360  MElement *e = *it;
361  int npts;
362  IntPt *GP;
363  double jac[3][3];
364  int integrationOrder = 2 * (e->getPolynomialOrder() + 5);
365  e->getIntegrationPoints(integrationOrder, &npts, &GP);
366  double val = 0.0;
367  for(int j = 0; j < npts; j++) {
368  double u = GP[j].pt[0];
369  double v = GP[j].pt[1];
370  double w = GP[j].pt[2];
371  double weight = GP[j].weight;
372  double detJ = fabs(e->getJacobian(u, v, w, jac));
373  SPoint3 p;
374  e->pnt(u, v, w, p);
375  double FEMVALUE;
376  solField.f(e, u, v, w, FEMVALUE);
377  double diff = (*sol)(p.x(), p.y(), p.z()) - FEMVALUE;
378  val += diff * diff * detJ * weight;
379  }
380  std::vector<double> vec;
381  vec.push_back(sqrt(val));
382  data[e->getNum()] = vec;
383  }
384  }
385 
386  PView *pv = new PView(errorFileName, "ElementData", pModel, data, 0.0, 1);
387  return pv;
388 }
389 
390 #endif
MElement::getNum
virtual std::size_t getNum() const
Definition: MElement.h:68
thermicSolver::computeL2Norm
double computeL2Norm(simpleFunction< double > *f)
Definition: thermicSolver.cpp:191
terms.h
ScalarLagrangeFunctionSpace
Definition: functionSpace.h:240
linearSystemFull
Definition: linearSystemFull.h:17
PView
Definition: PView.h:27
thermicField::_k
double _k
Definition: thermicSolver.h:33
thermicSolver::_tag
int _tag
Definition: thermicSolver.h:58
GaussQuadrature::ValVal
@ ValVal
Definition: quadratureRules.h:38
LoadTerm
Definition: terms.h:317
FilterDofTrivial
Definition: solverAlgorithms.h:226
linearSystemPETSc
Definition: linearSystemPETSc.h:150
MElement::getIntegrationPoints
virtual void getIntegrationPoints(int pOrder, int *npts, IntPt **pts)
Definition: MElement.h:436
linearSystemPETSc.h
SPoint3
Definition: SPoint3.h:14
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
NumberDofs
void NumberDofs(FunctionSpaceBase &space, Iterator itbegin, Iterator itend, Assembler &assembler)
Definition: solverAlgorithms.h:314
MElement::getParent
virtual MElement * getParent() const
Definition: MElement.h:231
BoundaryConditionT::ON_FACE
@ ON_FACE
Definition: thermicSolver.h:39
thermicSolver::assemble
void assemble(linearSystem< double > *lsys)
Definition: thermicSolver.cpp:111
PView.h
LoadTermOnBorder
Definition: terms.h:383
solverAlgorithms.h
linearSystemCSR.h
MPoint.h
thermicSolver::setEdgeTemp
void setEdgeTemp(int edge, simpleFunction< double > *f)
Definition: thermicSolver.cpp:91
thermicSolver::pModel
GModel * pModel
Definition: thermicSolver.h:57
groupOfElements
Definition: groupOfElements.h:24
BoundaryConditionT::ON_EDGE
@ ON_EDGE
Definition: thermicSolver.h:39
GModel::buildCutGModel
GModel * buildCutGModel(gLevelset *ls, bool cutElem=true, bool saveTri=false)
Definition: GModel.cpp:3376
PViewData.h
IntPt::pt
double pt[3]
Definition: GaussIntegration.h:13
dofManager::sizeOfR
virtual int sizeOfR() const
Definition: dofManager.h:606
thermicSolver::cutMesh
void cutMesh(gLevelset *ls)
Definition: thermicSolver.cpp:56
MElement::getNumVertices
virtual std::size_t getNumVertices() const =0
dirichletBCT::_f
simpleFunction< double > * _f
Definition: thermicSolver.h:46
GModel::readMSH
int readMSH(const std::string &name)
Definition: GModelIO_MSH.cpp:12
linearSystemCSRGmm::setGmres
void setGmres(int n)
Definition: linearSystemCSR.h:189
MElement::getVertex
virtual const MVertex * getVertex(int num) const =0
SPoint3::x
double x(void) const
Definition: SPoint3.h:125
thermicSolver::setMesh
virtual void setMesh(const std::string &meshFileName)
Definition: thermicSolver.cpp:27
solverField.h
IntPt::weight
double weight
Definition: GaussIntegration.h:14
SolverField
Definition: solverField.h:25
simpleFunction< double >
thermicSolver.h
gLevelset
Definition: gmshLevelset.h:64
Assemble
void Assemble(BilinearTermBase &term, FunctionSpaceBase &space, Iterator itbegin, Iterator itend, QuadratureBase &integrator, Assembler &assembler)
Definition: solverAlgorithms.h:19
thermicSolver::_dim
int _dim
Definition: thermicSolver.h:58
thermicSolver::LagrangeMultiplierSpace
FunctionSpace< double > * LagrangeMultiplierSpace
Definition: thermicSolver.h:61
linearSystemFull::systemSolve
virtual int systemSolve()
Definition: linearSystemFull.h:77
Numeric.h
GModel
Definition: GModel.h:44
dofManager::sizeOfF
virtual int sizeOfF() const
Definition: dofManager.h:610
thermicField::g
groupOfElements * g
Definition: thermicSolver.h:32
LagrangeMultiplierFieldT::_f
simpleFunction< double > * _f
Definition: thermicSolver.h:26
dirichletBCT
Definition: thermicSolver.h:45
LagrangeMultiplierFieldT::_tag
int _tag
Definition: thermicSolver.h:23
LaplaceTerm
Definition: terms.h:238
SPoint3::y
double y(void) const
Definition: SPoint3.h:127
GaussQuadrature::GradGrad
@ GradGrad
Definition: quadratureRules.h:38
thermicSolver::allDirichlet
std::vector< dirichletBCT > allDirichlet
Definition: thermicSolver.h:69
dofManager< double >
BoundaryConditionT::g
groupOfElements * g
Definition: thermicSolver.h:41
GModel::getNumRegions
std::size_t getNumRegions() const
Definition: GModel.h:344
MElement
Definition: MElement.h:30
linearSystemFull.h
Field
Definition: Field.h:103
linearSystemCSRGmm
Definition: linearSystemCSR.h:176
LagrangeMultiplierFieldT::_tau
double _tau
Definition: thermicSolver.h:25
GModel::writeMSH
int writeMSH(const std::string &name, double version=2.2, bool binary=false, bool saveAll=false, bool saveParametric=false, double scalingFactor=1.0, int elementStartNum=0, int saveSinglePartition=0, bool append=false)
Definition: GModelIO_MSH.cpp:76
MElement::pnt
virtual void pnt(double u, double v, double w, SPoint3 &p) const
Definition: MElement.cpp:1072
thermicSolver::LagrangeMultiplierFields
std::vector< LagrangeMultiplierFieldT > LagrangeMultiplierFields
Definition: thermicSolver.h:65
thermicSolver::changeLMTau
void changeLMTau(int tag, double tau)
Definition: thermicSolver.cpp:71
BoundaryConditionT::onWhat
location onWhat
Definition: thermicSolver.h:40
thermicField
Definition: thermicSolver.h:30
IntPt
Definition: GaussIntegration.h:12
quadratureRules.h
thermicSolver::setThermicDomain
void setThermicDomain(int phys, double k)
Definition: thermicSolver.cpp:62
thermicSolver::computeLagNorm
double computeLagNorm(int tag, simpleFunction< double > *f)
Definition: thermicSolver.cpp:229
thermicField::_tag
int _tag
Definition: thermicSolver.h:31
thermicSolver::pAssembler
dofManager< double > * pAssembler
Definition: thermicSolver.h:59
thermicSolver::solve
void solve()
Definition: thermicSolver.cpp:40
MPoint
Definition: MPoint.h:16
thermicSolver::thermicFields
std::vector< thermicField > thermicFields
Definition: thermicSolver.h:64
GaussQuadrature::Val
@ Val
Definition: quadratureRules.h:38
BoundaryConditionT::_tag
int _tag
Definition: thermicSolver.h:38
LagrangeMultiplierFieldT::g
groupOfElements * g
Definition: thermicSolver.h:24
SPoint3::z
double z(void) const
Definition: SPoint3.h:129
MElement::getJacobian
virtual double getJacobian(const fullMatrix< double > &gsf, double jac[3][3]) const
Definition: MElement.cpp:868
FixNodalDofs
void FixNodalDofs(FunctionSpaceBase &space, MElement *e, Assembler &assembler, simpleFunction< typename Assembler::dataVec > &fct, FilterDof &filter)
Definition: solverAlgorithms.h:270
GModel.h
LagrangeMultiplierTerm
Definition: terms.h:339
MElement::getPolynomialOrder
virtual int getPolynomialOrder() const
Definition: MElement.h:78
ScalarLagrangeFunctionSpaceOfElement
Definition: functionSpace.h:121
thermicSolver::allNeumann
std::vector< neumannBCT > allNeumann
Definition: thermicSolver.h:67
thermicSolver::setFaceTemp
void setFaceTemp(int face, simpleFunction< double > *f)
Definition: thermicSolver.cpp:101
linearSystemCSRGmm::setNoisy
void setNoisy(int n)
Definition: linearSystemCSR.h:188
gmshLevelset.h
functionSpace.h
linearSystem
Definition: linearSystem.h:38
thermicSolver::LagSpace
FunctionSpace< double > * LagSpace
Definition: thermicSolver.h:60
thermicSolver::setLagrangeMultipliers
void setLagrangeMultipliers(int phys, double tau, int tag, simpleFunction< double > *f)
Definition: thermicSolver.cpp:80
GaussQuadrature
Definition: quadratureRules.h:36
SolverField::f
virtual void f(MElement *ele, double u, double v, double w, ValType &val) const
Definition: solverField.h:53
LagrangeMultiplierFieldT
Definition: thermicSolver.h:22