G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsFlowUtils.h
Go to the documentation of this file.
1
14#pragma once
15
16#include <gismo.h>
17
18namespace gismo
19{
20
21#ifdef GISMO_WITH_PARDISO
24template <class T>
25inline void pardisoSetup(typename gsSparseSolver<T>::PardisoLU& solver)
26{
27 solver.setParam(7, 15);
28 solver.setParam(9, 13);
29 solver.setParam(12, 0);
30}
31#endif
32
33
34inline void startAnimationFile(std::ofstream& file)
35{
36 file << "<?xml version=\"1.0\"?>\n";
37 file << "<VTKFile type=\"Collection\" version=\"0.1\">";
38 file << "<Collection>\n";
39}
40
41
42inline void endAnimationFile(std::ofstream& file)
43{
44 file << "</Collection>\n";
45 file << "</VTKFile>\n";
46 file.close();
47}
48
49
55inline void gsWriteOutput(std::ofstream& file, const std::string output, bool fileOutput, bool dispInTerminal)
56{
57 if (fileOutput)
58 file << output;
59
60 if (dispInTerminal)
61 gsInfo << output;
62}
63
64
70inline void gsWriteOutputLine(std::ofstream& file, const std::string line, bool fileOutput, bool dispInTerminal)
71{
72 gsWriteOutput(file, line, fileOutput, dispInTerminal);
73
74 if (fileOutput)
75 file << std::endl;
76
77 if (dispInTerminal)
78 gsInfo << std::endl;
79}
80
81
84template<class T>
86{
87 std::map<T, bool> map;
88 std::vector<T> vecTmp;
89
90 for (index_t j = 0; j < mat.cols(); j++)
91 {
92 for (index_t i = 0; i < mat.rows(); i++)
93 {
94 if(map.count(mat(i,j)) == 0)
95 {
96 map[mat(i,j)] = true;
97 vecTmp.push_back(mat(i,j));
98 }
99 }
100 }
101
102 gsMatrix<T> vec(vecTmp.size(), 1);
103 for (size_t i = 0; i < vecTmp.size(); i++)
104 vec(i) = vecTmp[i];
105
106
107 return vec;
108}
109
110
115template<class T, int MatOrder>
117{
118 gsVector<index_t> nnzPerOuter(mat.outerSize());
119 nnzPerOuter.setZero();
120
121 for (index_t outer = 0; outer < mat.outerSize(); outer++)
122 for (typename gsSparseMatrix<T, MatOrder>::InnerIterator it(mat, outer); it; ++it)
123 ++nnzPerOuter[outer];
124
125 return nnzPerOuter;
126}
127
128
136template<class T, int MatOrder>
137void diagInvMatrix_into(const gsSparseMatrix<T, MatOrder>& mat, gsSparseMatrix<T, MatOrder>& diagInv, int repeat, bool lumping = false)
138{
139 GISMO_ENSURE(mat.nonZeros() != 0, "diagInvMatrix_into(): The matrix is empty!");
140
141 int varDofs = mat.rows();
142
143 diagInv.resize(repeat*varDofs, repeat*varDofs);
144 diagInv.reserve(gsVector<int>::Constant(diagInv.cols(), 1));
145
146 const gsSparseMatrix<T, MatOrder>* matPtr = &mat;
147 gsSparseMatrix<T, MatOrder> lumped(varDofs, varDofs);
148
149 if (lumping)
150 {
151 lumped.reserve(gsVector<int>::Constant(varDofs, 1));
152
153 for (int j = 0; j < varDofs; j++)
154 lumped.insert(j, j) = math::abs(mat.at(j, j)); // abs value because of "lumping" diag(A) in SIMPLE-type prec., does not change lumped mass matrix in IgA
155
156 for (int j = 0; j < varDofs; j++)
157 {
158 for (typename gsSparseMatrix<T, MatOrder>::InnerIterator it(mat, j); it; ++it)
159 {
160 int i = it.row();
161
162 if (i != j)
163 lumped.coeffRef(i, i) += math::abs(it.value());
164 }
165 }
166
167 matPtr = &lumped;
168 }
169
170 for (int i = 0; i < varDofs; i++)
171 {
172 T tmp = 1 / matPtr->coeff(i, i);
173
174 for (int s = 0; s < repeat; s++)
175 diagInv.coeffRef(i + s * varDofs, i + s * varDofs) = tmp;
176 }
177}
178
179
188template<class T>
189gsTensorBSpline<2, T> BSplineRectangle(int deg, const T llx, const T lly, const T a, const T b, int numSep = 0)
190{
191 gsKnotVector<T> kv(0, 1, numSep, deg + 1, deg); // first, last, num_inter, mult_end, mult_inter
192
193 int n = kv.size() - deg - 1;
194 gsMatrix<T> coef(n*n, 2);
195
196 for (int i = 0; i < n; i++)
197 for (int j = 0; j < n; j++)
198 coef.row(i + j*n) << llx + (i*a) / (deg*(numSep + 1)), lly + (j*b) / (deg*(numSep + 1));
199
200 return gsTensorBSpline<2, T>(kv, kv, coef);
201}
202
203
214template<class T>
215gsTensorBSpline<3, T> BSplineBlock(int deg, const T llx, const T lly, const T llz, const T a, const T b, const T c, int numSep = 0)
216{
217 gsKnotVector<T> kv(0, 1, numSep, deg + 1, deg);
218
219 int n = kv.size() - deg - 1;
220 gsMatrix<T> coef(n*n*n, 3);
221
222 for (int i = 0; i < n; i++)
223 for (int j = 0; j < n; j++)
224 for (int k = 0; k < n; k++)
225 coef.row(i + j*n + k*n*n) << llx + (i*a) / (deg*(numSep + 1)), lly + (j*b) / (deg*(numSep + 1)), llz + (k*c) / (deg*(numSep + 1));
226
227 return gsTensorBSpline<3, T>(kv, kv, kv, coef);
228}
229
230
238template<class T>
239gsMultiPatch<T> BSplineCavity2D(int deg, const T a, const T b, const int np = 1, int numSep = 0)
240{
242
243 T aPatch = a / np;
244 T bPatch = b / np;
245
246 for (int j = 0; j < np; j++)
247 for (int i = 0; i < np; i++)
248 mp.addPatch(BSplineRectangle(deg, i*aPatch, j*bPatch, aPatch, bPatch, numSep));
249
250 mp.computeTopology();
251
252 return mp;
253}
254
255
263template<class T>
264gsMultiPatch<T> BSplineCavity3D(int deg, const T a, const T b, const T c, int numSep = 0)
265{
267 mp.addPatch(BSplineBlock(deg, 0.0, 0.0, 0.0, a, b, c, numSep));
268 mp.computeTopology();
269 return mp;
270}
271
272
281template<class T>
282gsMultiPatch<T> BSplineStep2D(int deg, const T a, const T b, const T a_in, T h = 0, bool periodic = false)
283{
285
286 if (h == 0)
287 h = b / 2;
288
289 mp.addPatch(BSplineRectangle(deg, 0.0, 0.0, a, h));
290 mp.addPatch(BSplineRectangle(deg, 0.0, h, a, b - h));
291 mp.addPatch(BSplineRectangle(deg, -a_in, h, a_in, b - h));
292
293 mp.addInterface(0, boundary::north, 1, boundary::south);
294 mp.addInterface(1, boundary::west, 2, boundary::east);
295
296 if(periodic)
297 mp.addInterface(0, boundary::south, 1, boundary::north);
298
299 mp.addAutoBoundaries();
300
301 return mp;
302}
303
304
314template<class T>
315gsMultiPatch<T> BSplineStep3D(int deg, const T a, const T b, const T c, const T a_in, T h = 0, bool periodic = false)
316{
318
319 if (h == 0)
320 h = b / 2;
321
322 mp.addPatch(BSplineBlock<T>(deg, 0.0, 0.0, 0.0, a, h, c));
323 mp.addPatch(BSplineBlock<T>(deg, 0.0, h, 0.0, a, b - h, c));
324 mp.addPatch(BSplineBlock<T>(deg, -a_in, h, 0.0, a_in, b - h, c));
325
326 mp.addInterface(0, boundary::north, 1, boundary::south);
327 mp.addInterface(2, boundary::east, 1, boundary::west);
328
329 if (periodic)
330 {
331 mp.addInterface(0, boundary::front, (size_t)0, boundary::back);
332 mp.addInterface(1, boundary::front, 1, boundary::back);
333 mp.addInterface(2, boundary::front, 2, boundary::back);
334 }
335
336 mp.addAutoBoundaries();
337
338 return mp;
339}
340
341
349template<class T>
350void addBCs(gsBoundaryConditions<T>& bcInfo, std::vector<std::pair<int, boxSide> >& bndIn, std::vector<std::pair<int, boxSide> >& bndWall, gsFunctionExpr<T> Uin, gsFunctionExpr<T> Uwall)
351{
352 for (size_t i = 0; i < bndIn.size(); i++)
353 bcInfo.addCondition(bndIn[i].first, bndIn[i].second, condition_type::dirichlet, Uin);
354
355 for (size_t i = 0; i < bndWall.size(); i++)
356 bcInfo.addCondition(bndWall[i].first, bndWall[i].second, condition_type::dirichlet, Uwall);
357}
358
359
366template<class T>
367void defineBCs_cavity2D(gsBoundaryConditions<T>& bcInfo, const int np, std::vector<std::pair<int, boxSide> >& bndWall, std::string lidVel = "1")
368{
369 gsFunctionExpr<T> Uwall("0", "0", 2);
370 gsFunctionExpr<T> Ulid(lidVel, "0", 2);
371
372 for (int i = 1; i <= np; i++)
373 {
374 bcInfo.addCondition(np*np - i, boundary::north, condition_type::dirichlet, Ulid, 0);
375 bndWall.push_back(std::make_pair(np*np - i, boundary::north));
376 }
377
378 for (int i = 0; i < np; i++)
379 {
380 bcInfo.addCondition(i, boundary::south, condition_type::dirichlet, Uwall, 0);
381 bndWall.push_back(std::make_pair(i, boundary::south));
382 }
383
384 for (int i = 0; i < np; i++)
385 {
386 bcInfo.addCondition(i * np, boundary::west, condition_type::dirichlet, Uwall, 0);
387 bcInfo.addCondition((i + 1)*np - 1, boundary::east, condition_type::dirichlet, Uwall, 0);
388 bndWall.push_back(std::make_pair(i * np, boundary::west));
389 bndWall.push_back(std::make_pair((i + 1)*np - 1, boundary::east));
390 }
391}
392
393
399template<class T>
400void defineBCs_cavity3D(gsBoundaryConditions<T>& bcInfo, std::vector<std::pair<int, boxSide> >& bndWall, std::string lidVel = "1")
401{
402 gsFunctionExpr<T> Uwall("0", "0", "0", 3);
403 gsFunctionExpr<T> Ulid(lidVel, "0", "0", 3);
404
405 bcInfo.addCondition(0, boundary::north, condition_type::dirichlet, Ulid, 0);
406 bcInfo.addCondition(0, boundary::south, condition_type::dirichlet, Uwall, 0);
407 bcInfo.addCondition(0, boundary::west, condition_type::dirichlet, Uwall, 0);
408 bcInfo.addCondition(0, boundary::east, condition_type::dirichlet, Uwall, 0);
409 bcInfo.addCondition(0, boundary::front, condition_type::dirichlet, Uwall, 0);
410 bcInfo.addCondition(0, boundary::back, condition_type::dirichlet, Uwall, 0);
411 bndWall.push_back(std::make_pair(0, boundary::north));
412 bndWall.push_back(std::make_pair(0, boundary::south));
413 bndWall.push_back(std::make_pair(0, boundary::west));
414 bndWall.push_back(std::make_pair(0, boundary::east));
415 bndWall.push_back(std::make_pair(0, boundary::front));
416 bndWall.push_back(std::make_pair(0, boundary::back));
417}
418
419
427template<class T>
428void defineBCs_cavity(gsBoundaryConditions<T>& bcInfo, std::vector<std::pair<int, boxSide> >& bndWall, int dim, const int np = 1, std::string lidVel = "1")
429{
430 switch (dim)
431 {
432 case 2:
433 defineBCs_cavity2D(bcInfo, np, bndWall, lidVel);
434 break;
435 case 3:
436 defineBCs_cavity3D(bcInfo, bndWall, lidVel);
437 break;
438 default:
439 GISMO_ERROR("Wrong dimension!");
440 break;
441 }
442}
443
444
453template<class T>
454void defineBCs_step2D(gsBoundaryConditions<T>& bcInfo, std::vector<std::pair<int, boxSide> >& bndIn, std::vector<std::pair<int, boxSide> >& bndOut, std::vector<std::pair<int, boxSide> >& bndWall, bool periodic = false, std::string inVel = "default")
455{
456 if (inVel == "default")
457 inVel = "(-4*(y-1.5)^2 + 1)";
458
459 gsFunctionExpr<T> Uin, Uwall;
460 Uin = gsFunctionExpr<T>(inVel, "0", 2);
461 Uwall = gsFunctionExpr<T>("0", "0", 2);
462
463 if (!periodic)
464 {
465 bndIn.push_back(std::make_pair(2, boundary::west));
466 bndWall.push_back(std::make_pair(0, boundary::west));
467 bndWall.push_back(std::make_pair(0, boundary::south));
468 bndWall.push_back(std::make_pair(1, boundary::north));
469 bndWall.push_back(std::make_pair(2, boundary::south));
470 bndWall.push_back(std::make_pair(2, boundary::north));
471 bndOut.push_back(std::make_pair(0, boundary::east));
472 bndOut.push_back(std::make_pair(1, boundary::east));
473 }
474 else
475 {
476 bndIn.push_back(std::make_pair(2, boundary::west));
477 bndWall.push_back(std::make_pair(0, boundary::west));
478 bndWall.push_back(std::make_pair(2, boundary::south));
479 bndWall.push_back(std::make_pair(2, boundary::north));
480 bndOut.push_back(std::make_pair(0, boundary::east));
481 bndOut.push_back(std::make_pair(1, boundary::east));
482 }
483
484 addBCs(bcInfo, bndIn, bndWall, Uin, Uwall);
485}
486
487
496template<class T>
497void defineBCs_step3D(gsBoundaryConditions<T>& bcInfo, std::vector<std::pair<int, boxSide> >& bndIn, std::vector<std::pair<int, boxSide> >& bndOut, std::vector<std::pair<int, boxSide> >& bndWall, bool periodic = false, std::string inVel = "default")
498{
499 gsFunctionExpr<T> Uin, Uwall;
500
501 if (!periodic)
502 {
503 if (inVel == "default")
504 inVel = "(-4*(y-1.5)^2 + 1)*(-(z-1)^2 + 1)";
505
506 Uin = gsFunctionExpr<T>(inVel, "0", "0", 3);
507 Uwall = gsFunctionExpr<T>("0", "0", "0", 3);
508
509 bndIn.push_back(std::make_pair(2, boundary::west));
510 bndWall.push_back(std::make_pair(0, boundary::west));
511 bndWall.push_back(std::make_pair(0, boundary::south));
512 bndWall.push_back(std::make_pair(0, boundary::front));
513 bndWall.push_back(std::make_pair(0, boundary::back));
514 bndWall.push_back(std::make_pair(1, boundary::north));
515 bndWall.push_back(std::make_pair(1, boundary::front));
516 bndWall.push_back(std::make_pair(1, boundary::back));
517 bndWall.push_back(std::make_pair(2, boundary::south));
518 bndWall.push_back(std::make_pair(2, boundary::north));
519 bndWall.push_back(std::make_pair(2, boundary::front));
520 bndWall.push_back(std::make_pair(2, boundary::back));
521 bndOut.push_back(std::make_pair(0, boundary::east));
522 bndOut.push_back(std::make_pair(1, boundary::east));
523 }
524 else
525 {
526 if (inVel == "default")
527 inVel = "(-4*(y-1.5)^2 + 1)";
528
529 Uin = gsFunctionExpr<T>(inVel, "0", "0", 3);
530 Uwall = gsFunctionExpr<T>("0", "0", "0", 3);
531
532 bndIn.push_back(std::make_pair(2, boundary::west));
533 bndWall.push_back(std::make_pair(0, boundary::west));
534 bndWall.push_back(std::make_pair(0, boundary::south));
535 bndWall.push_back(std::make_pair(1, boundary::north));
536 bndWall.push_back(std::make_pair(2, boundary::south));
537 bndWall.push_back(std::make_pair(2, boundary::north));
538 bndOut.push_back(std::make_pair(0, boundary::east));
539 bndOut.push_back(std::make_pair(1, boundary::east));
540 }
541
542 addBCs(bcInfo, bndIn, bndWall, Uin, Uwall);
543}
544
545
555template<class T>
556void defineBCs_step(gsBoundaryConditions<T>& bcInfo, std::vector<std::pair<int, boxSide> >& bndIn, std::vector<std::pair<int, boxSide> >& bndOut, std::vector<std::pair<int, boxSide> >& bndWall, int dim, bool periodic = false, std::string inVel = "default")
557{
558 switch (dim)
559 {
560 case 2:
561 defineBCs_step2D(bcInfo, bndIn, bndOut, bndWall, periodic, inVel);
562 break;
563 case 3:
564 defineBCs_step3D(bcInfo, bndIn, bndOut, bndWall, periodic, inVel);
565 break;
566 default:
567 GISMO_ERROR("Wrong dimension!");
568 break;
569 }
570}
571
572
582template<class T>
583void defineBCs_profile2D(gsBoundaryConditions<T>& bcInfo, std::vector<std::pair<int, boxSide> >& bndIn, std::vector<std::pair<int, boxSide> >& bndOut, std::vector<std::pair<int, boxSide> >& bndWall, T inVelX, T inVelY)
584{
586 gsFunctionExpr<T> Uwall = gsFunctionExpr<T>("0", "0", 2);
587
588 bndIn.push_back(std::make_pair(0, boundary::west));
589 bndWall.push_back(std::make_pair(1, boundary::north));
590 bndWall.push_back(std::make_pair(1, boundary::south));
591 bndOut.push_back(std::make_pair(2, boundary::east));
592
593 addBCs(bcInfo, bndIn, bndWall, Uin, Uwall);
594}
595
596
604template< int d, class T>
605void refineFirstKnotSpan(gsMultiBasis<T>& basis, int numRefine, int patch, int dir)
606{
607 const gsTensorBSplineBasis<d, T>* patchBasis = dynamic_cast<const gsTensorBSplineBasis<d, T>*>(&(basis.basis(patch)));
608 gsMatrix<T> box(d, 2);
609
610 for (int i = 0; i < numRefine; i++)
611 {
612 box.setZero();
613 T knot = patchBasis->knot(dir, patchBasis->degree(dir) + 1);
614 box(dir, 1) = knot;
615 basis.refine(patch, box);
616 }
617}
618
619
627template< int d, class T>
628void refineLastKnotSpan(gsMultiBasis<T>& basis, int numRefine, int patch, int dir)
629{
630 const gsTensorBSplineBasis<d, T>* patchBasis = dynamic_cast<const gsTensorBSplineBasis<d, T>*>(&(basis.basis(patch)));
631 gsMatrix<T> box(d, 2);
632
633 for (int i = 0; i < numRefine; i++)
634 {
635 box.setZero();
636 int sizeKnots = patchBasis->knots(dir).size() - 1;
637 T lastKnot = patchBasis->knot(dir, sizeKnots);
638 T knot = patchBasis->knot(dir, sizeKnots - (patchBasis->degree(dir) + 1));
639 box(dir, 0) = knot;
640 box(dir, 1) = lastKnot;
641 basis.refine(patch, box);
642 }
643}
644
645
653template<class T>
654void refineBasis_cavity(gsMultiBasis<T>& basis, int numRefine, int numRefineLocal, int dim, int numSep = 0)
655{
656 switch (dim)
657 {
658 case 2:
659 {
660 int npDir = math::sqrt(basis.nPieces());
661 int npRef = std::log2(npDir);
662 int sepRef = std::log2(numSep + 1);
663
664 for (int i = 0; i < numRefine - npRef - sepRef; ++i)
665 basis.uniformRefine();
666
667 if (numRefineLocal && npDir == 1)
668 {
669 for (int dir = 0; dir < dim; dir++)
670 {
671 refineFirstKnotSpan<2, T>(basis, numRefineLocal, 0, dir);
672 refineLastKnotSpan<2, T>(basis, numRefineLocal, 0, dir);
673 }
674 }
675
676 break;
677 }
678 case 3:
679 {
680 for (int i = 0; i < numRefine; ++i)
681 basis.uniformRefine();
682
683 for (int dir = 0; dir < dim; dir++)
684 {
685 refineFirstKnotSpan<3, T>(basis, numRefineLocal, 0, dir);
686 refineLastKnotSpan<3, T>(basis, numRefineLocal, 0, dir);
687 }
688
689 break;
690 }
691 default:
692 GISMO_ERROR("Wrong dimension!");
693 break;
694 }
695}
696
697
704template<int d, class T>
705void refineLocal_step(gsMultiBasis<T>& basis, int numRefineWalls, int numRefineCorner)
706{
707 // refinement near upper and bottom walls
708 refineFirstKnotSpan<d, T>(basis, numRefineWalls, 0, 1);
709 refineLastKnotSpan<d, T>(basis, numRefineWalls, 1, 1);
710 refineLastKnotSpan<d, T>(basis, numRefineWalls, 2, 1);
711
712 // refinement near the corner
713 refineFirstKnotSpan<d, T>(basis, numRefineCorner, 0, 0);
714 refineFirstKnotSpan<d, T>(basis, numRefineCorner, 1, 0);
715 refineLastKnotSpan<d, T>(basis, numRefineCorner, 2, 0);
716 refineLastKnotSpan<d, T>(basis, numRefineCorner, 0, 1);
717 refineFirstKnotSpan<d, T>(basis, numRefineCorner, 1, 1);
718 refineFirstKnotSpan<d, T>(basis, numRefineCorner, 2, 1);
719}
720
721
734template<class T>
735void refineBasis_step(gsMultiBasis<T>& basis, int numRefine, int numRefineWalls, int numRefineCorner, int numRefineU, real_t addRefPart, int dim, real_t a, real_t b, real_t c = 0.0)
736{
737 for (int i = 0; i < numRefine; ++i)
738 basis.uniformRefine();
739
740 gsMatrix<T> box(dim, 2);
741
742 int uRefine = math::floor(std::log2(a / b)) + 1 + numRefineU;
743 box.setZero();
744 box(0, 1) = 1;
745 for (int i = 0; i < uRefine; i++)
746 for (int p = 0; p < 2; p++)
747 basis.refine(p, box);
748
749 if (dim == 3)
750 {
751 int wRefine = math::floor(std::log2(c / b)) + 1;
752 box.setZero();
753 box(2, 1) = 1;
754 for (int i = 0; i < wRefine; i++)
755 for (int p = 0; p < 3; p++)
756 basis.refine(p, box);
757 }
758
759 box.setZero();
760 box(0,1) = addRefPart;
761 for (int p = 0; p < 2; p++)
762 basis.refine(p, box);
763
764 switch (dim)
765 {
766 case 2:
767 refineLocal_step<2, T>(basis, numRefineWalls, numRefineCorner);
768 break;
769 case 3:
770 refineLocal_step<3, T>(basis, numRefineWalls, numRefineCorner);
771 break;
772 default:
773 GISMO_ERROR("Wrong dimension!");
774 break;
775 }
776}
777
778
785template<class T>
786void refineBasis_profile2D(gsMultiBasis<T>& basis, int numRefine, int numRefineBlade, int numRefineLead)
787{
788 for (int i = 0; i < numRefine; ++i)
789 basis.uniformRefine();
790
791 if (numRefineBlade)
792 {
793 for (int p = 0; p < basis.nPieces(); p++)
794 {
795 refineFirstKnotSpan<2, T>(basis, numRefineBlade, p, 1);
796 refineLastKnotSpan<2, T>(basis, numRefineBlade, p, 1);
797 }
798 }
799
800 if (numRefineLead)
801 {
802 refineLastKnotSpan<2, T>(basis, numRefineLead, 0, 0);
803 refineFirstKnotSpan<2, T>(basis, numRefineLead, 1, 0);
804 }
805}
806
807
808template<class T>
809void plotQuantityFromSolution(std::string quantity, const gsField<T>& solField, std::string const & fn, unsigned npts)
810{
811 gsParaviewCollection pwCollection(fn);
812 std::string fileName;
813
814 for (unsigned int p = 0; p < solField.patches().nPatches(); p++)
815 {
816 fileName = fn + util::to_string(p);
817
818 gsMatrix<T> geoVals, quantityVals;
820
821 gsGeometry<T>* patch = &solField.patches().patch(p);
822 const int parDim = patch->domainDim();
823 const int tarDim = patch->targetDim();
824
825 gsMatrix<T> ab = patch->support();
826 gsVector<T> a = ab.col(0);
827 gsVector<T> b = ab.col(1);
828 np = uniformSampleCount(a, b, npts);
829 gsMatrix<T> pts = gsPointGrid(a, b, np);
830
831 // evaluate geometry at pts
832 geoVals = patch->eval(pts);
833
834 if (3 - parDim > 0)
835 {
836 np.conservativeResize(3);
837 np.bottomRows(3 - parDim).setOnes();
838 }
839 if (3 - tarDim > 0)
840 {
841 geoVals.conservativeResize(3, geoVals.cols());
842 geoVals.bottomRows(3 - tarDim).setZero();
843 }
844
845 // evaluate quantity at pts
846 if (quantity == "divergence")
847 solField.function(p).div_into(pts, quantityVals); // incorrect?? (derivatives in parametric space?)
848 else
849 GISMO_ERROR("Function plotQuantityFromSolution for " + quantity + " not implemented.");
850
851 // paraview export
852 gsWriteParaviewTPgrid(geoVals, quantityVals, np.template cast<index_t>(), fileName);
853
854 pwCollection.addPart(fileName + ".vts");
855 }
856 pwCollection.save();
857}
858
859
860// -----------------------------------------------
861
862
863template<class T>
864struct gsVectorHash
865{
866 std::size_t operator()(const gsVector<T>& vec) const
867 {
868 std::size_t seed = vec.size();
869 for (int i = 0; i < vec.size(); i++)
870 seed ^= std::hash<T>()(vec(i)) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
871
872 return seed;
873 }
874};
875
876
877inline index_t mapTensorID(index_t i, index_t j, index_t k, size_t size1, size_t size2)
878{
879 index_t result = (k*size1*size2)+(j*size1)+i;
880 return result;
881}
882
883
884} //namespace gismo
Class containing a set of boundary conditions.
Definition gsBoundaryConditions.h:342
void addCondition(int p, boxSide s, condition_type::type t, gsFunctionSet< T > *f, short_t unknown=0, bool parametric=false, int comp=-1)
Adds another boundary condition.
Definition gsBoundaryConditions.h:650
A scalar of vector field defined on a m_parametric geometry.
Definition gsField.h:55
const gsFunction< T > & function(int i=0) const
Returns the gsFunction of patch i.
Definition gsField.h:231
const gsMultiPatch< T > & patches() const
Returns gsMultiPatch containing the geometric information on the domain.
Definition gsField.h:210
Class defining a multivariate (real or vector) function given by a string mathematical expression.
Definition gsFunctionExpr.h:52
Abstract base class representing a geometry map.
Definition gsGeometry.h:93
Class for representing a knot vector.
Definition gsKnotVector.h:80
size_t size() const
Number of knots (including repetitions).
Definition gsKnotVector.h:242
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Holds a set of patch-wise bases and their topology information.
Definition gsMultiBasis.h:37
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition gsMultiPatch.h:100
This class is used to create a Paraview .pvd (collection) file.
Definition gsParaviewCollection.h:77
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition gsSparseMatrix.h:139
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
A tensor product of d B-spline functions, with arbitrary target dimension.
Definition gsTensorBSpline.h:45
short_t degree(short_t i) const
Returns the degree of the basis wrt variable i.
Definition gsTensorBasis.h:465
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
Main header to be included by clients using the G+Smo library.
std::string to_string(const C &value)
Converts value to string, assuming "operator<<" defined on C.
Definition gsUtils.h:56
gsMatrix< T > gsPointGrid(gsVector< T > const &a, gsVector< T > const &b, gsVector< unsigned > const &np)
Construct a Cartesian grid of uniform points in a hypercube, using np[i] points in direction i.
Definition gsPointGrid.hpp:82
#define index_t
Definition gsConfig.h:32
#define GISMO_ERROR(message)
Definition gsDebug.h:118
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
#define gsInfo
Definition gsDebug.h:43
The G+Smo namespace, containing all definitions for the library.
gsMultiPatch< T > BSplineStep2D(int deg, const T a, const T b, const T a_in, T h=0, bool periodic=false)
Returns a B-spline multipatch domain for 2D problems of flow over a backward facing step.
Definition gsFlowUtils.h:282
gsTensorBSpline< 2, T > BSplineRectangle(int deg, const T llx, const T lly, const T a, const T b, int numSep=0)
Returns a B-spline parametrization of a rectangle of a given degree in both directions.
Definition gsFlowUtils.h:189
void defineBCs_profile2D(gsBoundaryConditions< T > &bcInfo, std::vector< std::pair< int, boxSide > > &bndIn, std::vector< std::pair< int, boxSide > > &bndOut, std::vector< std::pair< int, boxSide > > &bndWall, T inVelX, T inVelY)
Define boundary conditions for the 2D blade profile problem.
Definition gsFlowUtils.h:583
void defineBCs_cavity(gsBoundaryConditions< T > &bcInfo, std::vector< std::pair< int, boxSide > > &bndWall, int dim, const int np=1, std::string lidVel="1")
Define boundary conditions for the lid-driven cavity problem.
Definition gsFlowUtils.h:428
gsMultiPatch< T > BSplineStep3D(int deg, const T a, const T b, const T c, const T a_in, T h=0, bool periodic=false)
Returns a B-spline multipatch domain for 3D problems of flow over a backward facing step.
Definition gsFlowUtils.h:315
void defineBCs_step2D(gsBoundaryConditions< T > &bcInfo, std::vector< std::pair< int, boxSide > > &bndIn, std::vector< std::pair< int, boxSide > > &bndOut, std::vector< std::pair< int, boxSide > > &bndWall, bool periodic=false, std::string inVel="default")
Define boundary conditions for the 2D backward-facing step problem.
Definition gsFlowUtils.h:454
void addBCs(gsBoundaryConditions< T > &bcInfo, std::vector< std::pair< int, boxSide > > &bndIn, std::vector< std::pair< int, boxSide > > &bndWall, gsFunctionExpr< T > Uin, gsFunctionExpr< T > Uwall)
Define boundary conditions for the corresponding boundary parts.
Definition gsFlowUtils.h:350
void refineLocal_step(gsMultiBasis< T > &basis, int numRefineWalls, int numRefineCorner)
Refine basis for the backward-facing step problem near walls.
Definition gsFlowUtils.h:705
void refineBasis_step(gsMultiBasis< T > &basis, int numRefine, int numRefineWalls, int numRefineCorner, int numRefineU, real_t addRefPart, int dim, real_t a, real_t b, real_t c=0.0)
Refine basis for the backward-facing step problem.
Definition gsFlowUtils.h:735
void refineBasis_cavity(gsMultiBasis< T > &basis, int numRefine, int numRefineLocal, int dim, int numSep=0)
Refine basis for the 2D lid-driven cavity problem.
Definition gsFlowUtils.h:654
gsMatrix< T > createVectorOfUniqueIndices(const gsMatrix< T > &mat)
Creates a one-column matrix (vector) of unique values from the input matrix (useful for creating a un...
Definition gsFlowUtils.h:85
gsMultiPatch< T > BSplineCavity2D(int deg, const T a, const T b, const int np=1, int numSep=0)
Returns a B-spline multipatch domain for 2D problems of flow in a cavity.
Definition gsFlowUtils.h:239
void gsWriteOutputLine(std::ofstream &file, const std::string line, bool fileOutput, bool dispInTerminal)
Writes an output line into the given file and optionally also into terminal.
Definition gsFlowUtils.h:70
void defineBCs_cavity2D(gsBoundaryConditions< T > &bcInfo, const int np, std::vector< std::pair< int, boxSide > > &bndWall, std::string lidVel="1")
Define boundary conditions for the 2D lid-driven cavity problem.
Definition gsFlowUtils.h:367
gsTensorBSpline< 3, T > BSplineBlock(int deg, const T llx, const T lly, const T llz, const T a, const T b, const T c, int numSep=0)
Returns a B-spline parametrization of a 3D block of a given degree in all directions.
Definition gsFlowUtils.h:215
gsMultiPatch< T > BSplineCavity3D(int deg, const T a, const T b, const T c, int numSep=0)
Returns a B-spline multipatch domain for 3D problems of flow in a cavity.
Definition gsFlowUtils.h:264
void defineBCs_cavity3D(gsBoundaryConditions< T > &bcInfo, std::vector< std::pair< int, boxSide > > &bndWall, std::string lidVel="1")
Define boundary conditions for the 3D lid-driven cavity problem.
Definition gsFlowUtils.h:400
void refineFirstKnotSpan(gsMultiBasis< T > &basis, int numRefine, int patch, int dir)
Refine basis near wall (the first knot span).
Definition gsFlowUtils.h:605
gsVector< index_t > getNnzVectorPerOuter(const gsSparseMatrix< T, MatOrder > &mat)
Get a vector of nonzero entries per outer index (row or column depending on the matrix storage order)...
Definition gsFlowUtils.h:116
void diagInvMatrix_into(const gsSparseMatrix< T, MatOrder > &mat, gsSparseMatrix< T, MatOrder > &diagInv, int repeat, bool lumping=false)
Fill a diagonal approximation of an inverse matrix.
Definition gsFlowUtils.h:137
void refineBasis_profile2D(gsMultiBasis< T > &basis, int numRefine, int numRefineBlade, int numRefineLead)
Refine basis for the 2D profile problem.
Definition gsFlowUtils.h:786
void gsWriteOutput(std::ofstream &file, const std::string output, bool fileOutput, bool dispInTerminal)
Writes an output into the given file and optionally also into terminal.
Definition gsFlowUtils.h:55
void defineBCs_step3D(gsBoundaryConditions< T > &bcInfo, std::vector< std::pair< int, boxSide > > &bndIn, std::vector< std::pair< int, boxSide > > &bndOut, std::vector< std::pair< int, boxSide > > &bndWall, bool periodic=false, std::string inVel="default")
Define boundary conditions for the 3D backward-facing step problem.
Definition gsFlowUtils.h:497
void refineLastKnotSpan(gsMultiBasis< T > &basis, int numRefine, int patch, int dir)
Refine basis near wall (the last knot span).
Definition gsFlowUtils.h:628
void defineBCs_step(gsBoundaryConditions< T > &bcInfo, std::vector< std::pair< int, boxSide > > &bndIn, std::vector< std::pair< int, boxSide > > &bndOut, std::vector< std::pair< int, boxSide > > &bndWall, int dim, bool periodic=false, std::string inVel="default")
Define boundary conditions for the backward-facing step problem.
Definition gsFlowUtils.h:556
@ dirichlet
Dirichlet type.
Definition gsBoundaryConditions.h:31