G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsFlowSolverBase.hpp
Go to the documentation of this file.
1
12#pragma once
14#include <unordered_set>
15
16namespace gismo
17{
18
19template<class T, int MatOrder>
21{
22 m_solution.setZero(getAssembler()->numDofs(), 1);
23 m_iterationNumber = 0;
24 m_relNorm = std::numeric_limits<T>::infinity();
25
26 m_fileOutput = m_params.options().getSwitch("fileOutput");
27 m_dispOutput = !m_params.options().getSwitch("quiet");
28
29 if(m_fileOutput)
30 createOutputFile();
31
32 m_initAssembT = 0;
33 m_assembT = 0;
34}
35
36
37template<class T, int MatOrder>
39{
40 m_solution.setZero(getAssembler()->numDofs(), 1);
41}
42
43
44template<class T, int MatOrder>
46{
47 std::string fileName = m_params.options().getString("outFile");
48
49 if (fileName == "")
50 fileName = this->getName() + "_output.txt";
51
52 m_outFile.open(fileName);
53
54 std::stringstream output;
55 output << "\n" << m_params.options() << "\n";
56 gsWriteOutput(m_outFile, output.str(), m_fileOutput, false);
57}
58
59
60template<class T, int MatOrder>
62{
63
64#ifdef GISMO_WITH_PETSC
65 if (m_params.options().getSwitch("parallel"))
66 {
67 MPI_Barrier(PETSC_COMM_WORLD);
68 return MPI_Wtime();
69 }
70 else
71#endif
72 m_clock.restart();
73
74 return 0.0;
76
77
78template<class T, int MatOrder>
80{
82#ifdef GISMO_WITH_PETSC
83 if (m_params.options().getSwitch("parallel"))
84 {
85 MPI_Barrier(PETSC_COMM_WORLD);
86 return MPI_Wtime();
87 }
88 else
89#endif
90 return m_clock.stop();
91
92}
94
95template<class T, int MatOrder>
97{
98 if (!getAssembler()->isInitialized())
99 {
100 real_t time0 = stopwatchStart();
101 getAssembler()->initialize();
102 real_t time1 = stopwatchStop();
103
104 m_initAssembT += time1 - time0;
105 }
106
107 m_linSolverPtr = createLinSolver<T, MatOrder>(m_params, getAssembler());
108}
109
110
111template<class T, int MatOrder>
112void gsFlowSolverBase<T, MatOrder>::nextIteration(const unsigned numberOfIterations)
113{
114 GISMO_ASSERT(getAssembler()->isInitialized(), "Assembler must be initialized first, call initialize()");
115
116 for (unsigned iter = 0; iter < numberOfIterations; iter++)
117 nextIteration();
118}
119
121template<class T, int MatOrder>
122void gsFlowSolverBase<T, MatOrder>::solve(const int maxIterations, const T epsilon, const int minIterations)
123{
124 GISMO_ASSERT(getAssembler()->isInitialized(), "Assembler must be initialized first, call initialize()");
125 int iter = 0;
126 m_relNorm = solutionChangeRelNorm();
127
128 while ((iter < minIterations) || ((m_relNorm > epsilon) && (iter < maxIterations)))
129 {
130 m_outStream.str("");
131 m_outStream << "Iteration number " << m_iterationNumber + 1 << "...";
132 gsWriteOutput(m_outFile, m_outStream.str(), m_fileOutput, m_dispOutput);
133
134 nextIteration();
135 m_relNorm = solutionChangeRelNorm();
136
137 m_outStream.str("");
138 m_outStream << " Solution change relative norm: " << m_relNorm;
139 gsWriteOutputLine(m_outFile, m_outStream.str(), m_fileOutput, m_dispOutput);
140
141 iter++;
143}
144
145
146template<class T, int MatOrder>
148{
149 real_t time0 = stopwatchStart();
150 getAssembler()->update(sol, updateSol);
151 real_t time1 = stopwatchStop();
152
153 m_assembT += time1 - time0;
154}
155
156
157template<class T, int MatOrder>
159{
160 T relNorm;
162 if (m_iterationNumber)
163 relNorm = solutionChangeRelNorm(getAssembler()->getSolution(), m_solution);
164 else
165 relNorm = std::numeric_limits<T>::infinity();
166
167 return relNorm;
169
170
171template<class T, int MatOrder>
173{
174 gsMatrix<T> solChangeVector = solOld - solNew;
175 T relNorm = solChangeVector.norm() / solNew.norm();
176
177 return relNorm;
178}
179
180
181template<class T, int MatOrder>
183{
184 m_outStream.str("");
185 m_outStream << " [u, p] solution change relative norm: ";
186
187 for (int i = 0; i < solOld.cols(); i++)
188 m_outStream << solutionChangeRelNorm(solOld.col(i), solNew.col(i)) << ", ";
189
190 gsWriteOutputLine(m_outFile, m_outStream.str(), m_fileOutput, m_dispOutput);
191}
192
193
194template<class T, int MatOrder>
195void gsFlowSolverBase<T, MatOrder>::markDofsAsEliminatedZeros(const std::vector< gsMatrix< index_t > > & boundaryDofs, const int unk)
196{
197 getAssembler()->markDofsAsEliminatedZeros(boundaryDofs, unk);
198 updateSizes();
199}
200
201
202template<class T, int MatOrder>
204{
205 // default values
206
207 if (npts == -1)
208 npts = m_params.options().getInt("jac.npts");
209
210 if (dist == -1)
211 dist = m_params.options().getReal("jac.dist");
212
213 if (tol == -1)
214 tol = m_params.options().getReal("jac.tol");
215
216 short_t dim = m_params.getPde().patches().domainDim();
217 size_t np = m_params.getPde().patches().nPatches();
218
219 npts = math::pow(math::abs(npts), dim-1); // number of pts on one patch side
220 dist = math::abs(dist);
221 tol = math::abs(tol);
222
223 for (size_t p = 0; p < np; p++)
224 {
225 const gsGeometry<T>* patch = &m_params.getPde().patches().patch(p);
226
227 gsMatrix<T> parRange = patch->support();
228 GISMO_ASSERT(parRange.rows() == dim, "checkGeoJacobian: something went wrong, parRange.rows() != dim.");
229
230 std::unordered_set<gsVector<T>, gsVectorHash<T> > uniquePts; // set of unique instances of generated points
231 gsMatrix<T> pts(dim, npts);
232
233 for (short_t i = 0; i < dim; i++) // direction i fixed
234 {
235 gsMatrix<T> reducedRange(dim-1, parRange.cols()); // parameter range without direction i
236
237 if (i > 0)
238 reducedRange.topRows(i) = parRange.topRows(i);
239
240 if (i < dim - 1)
241 reducedRange.bottomRows(dim - i - 1) = parRange.bottomRows(dim - i - 1);
242
243 // first and last point shifted by dist from walls
244 reducedRange.col(0).array() += dist;
245 reducedRange.col(1).array() -= dist;
246
247 gsMatrix<T> reducedPts = gsPointGrid(reducedRange, npts); // uniformly distributed points in the reduced range
248
249 if (i > 0)
250 pts.topRows(i) = reducedPts.topRows(i);
251
252 if (i < dim - 1)
253 pts.bottomRows(dim - i - 1) = reducedPts.bottomRows(dim - i - 1);
254
255 pts.row(i) = gsVector<T>::Constant(pts.cols(), parRange(i,0) + dist); // fixed coordinate in direction i (lower+dist)
256
257 for(int j = 0; j < pts.cols(); j++)
258 uniquePts.insert(pts.col(j));
259
260 pts.row(i) = gsVector<T>::Constant(pts.cols(), parRange(i,1) - dist); // fixed coordinate in direction i (upper-dist)
261
262 for(int j = 0; j < pts.cols(); j++)
263 uniquePts.insert(pts.col(j));
264
265 }
266
267 for (const gsVector<T>& pt : uniquePts)
268 {
269 real_t jacDet = patch->jacobian(pt).determinant();
270
271 if (jacDet < 0)
272 {
273 gsWarn << "Negative geometry jacobian!\n";
274 return -1;
275 }
276
277 if (jacDet < tol)
278 {
279 gsWarn << "Geometry jacobian close to zero!\n";
280 return 1;
281 }
282 }
283
284 gsInfo << "\n";
285 }
286
287 return 0;
288}
289
290
291} // namespace gismo
virtual void nextIteration()
Perform next iteration step.
Definition gsFlowSolverBase.h:110
virtual void initialize()
Initialize the solver.
Definition gsFlowSolverBase.hpp:96
T solutionChangeRelNorm() const
Compute and return the relative norm of the solution change.
Definition gsFlowSolverBase.hpp:158
virtual void writeSolChangeRelNorm(gsMatrix< T > solOld, gsMatrix< T > solNew)
Compute and display the relative norm of the solution change given the two successive solutions.
Definition gsFlowSolverBase.hpp:182
real_t stopwatchStart()
Start measuring time (decides whether to use gsStopwatch or MPI_Wtime)
Definition gsFlowSolverBase.hpp:61
virtual void markDofsAsEliminatedZeros(const std::vector< gsMatrix< index_t > > &boundaryDofs, const int unk)
Eliminate given DOFs as homogeneous Dirichlet boundary.
Definition gsFlowSolverBase.hpp:195
void solve(const int maxIterations, const T epsilon=1e-3, const int minIterations=1)
Solve the incompressible Navier-Stokes problem.
Definition gsFlowSolverBase.hpp:122
virtual void initMembers()
Initialize all members.
Definition gsFlowSolverBase.hpp:20
virtual void createOutputFile()
Create output file.
Definition gsFlowSolverBase.hpp:45
real_t stopwatchStop()
Stop measuring time (decides whether to use gsStopwatch or MPI_Wtime)
Definition gsFlowSolverBase.hpp:79
virtual void updateAssembler(const gsMatrix< T > &sol, bool updateSol=true)
Update the assembler with a given solution.
Definition gsFlowSolverBase.hpp:147
virtual void updateSizes()
Update sizes of members (when DOF numbers change, e.g. after markDofsAsEliminatedZeros()).
Definition gsFlowSolverBase.hpp:38
int checkGeoJacobian(int npts=-1, T dist=-1, T tol=-1)
Check values of jacobian near boundaries of all patches.
Definition gsFlowSolverBase.hpp:203
Abstract base class representing a geometry map.
Definition gsGeometry.h:93
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
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 short_t
Definition gsConfig.h:35
#define gsWarn
Definition gsDebug.h:50
#define gsInfo
Definition gsDebug.h:43
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
The G+Smo namespace, containing all definitions for the library.
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 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