29 gsPartitionedFSI<T>::gsPartitionedFSI(gsNsTimeIntegrator<T> & nsSolver,
30 gsMultiPatch<T> & velocity, gsMultiPatch<T> & pressure,
31 gsElTimeIntegrator<T> & elSolver,
32 gsMultiPatch<T> & displacement,
34 gsMultiPatch<T> & aleDisplacement, gsMultiPatch<T> & aleVelocity) :
39 m_displacement(displacement),
40 m_aleSolver(aleSolver),
41 m_ALEdisplacment(aleDisplacement),
42 m_ALEvelocity(aleVelocity),
43 m_options(defaultOptions())
49 gsOptionList gsPartitionedFSI<T>::defaultOptions()
52 opt.addInt(
"MaxIter",
"Maximum number of coupling iterations per time step",10);
53 opt.addReal(
"AbsTol",
"Absolute tolerance for the convergence creterion",1e-10);
54 opt.addReal(
"RelTol",
"Absolute tolerance for the convergence creterion",1e-6);
55 opt.addInt(
"Verbosity",
"Amount of information printed to the terminal: none, some, all",solver_verbosity::none);
60 bool gsPartitionedFSI<T>::makeTimeStep(T timeStep)
63 m_nsSolver.saveState();
64 m_elSolver.saveState();
65 m_aleSolver.saveState();
74 nsTime = elTime = aleTime = 0.;
76 gsMultiPatch<> dispOldOld, dispOld, dispOldGuess;
78 while (numIter < m_options.getInt(
"MaxIter") && !converged)
83 m_elSolver.recoverState();
85 m_elSolver.makeTimeStep(timeStep);
89 m_elSolver.constructSolution(dispOldOld);
90 m_elSolver.constructSolution(m_displacement);
92 else if (numIter == 1)
94 m_elSolver.constructSolution(dispOld);
95 m_elSolver.constructSolution(dispOldGuess);
96 m_elSolver.constructSolution(m_displacement);
97 gsMatrix<> vecA, vecB;
98 formVector(dispOldOld,vecA);
99 formVector(m_displacement,vecB);
100 absResNorm = initResNorm = (vecB-vecA).norm()/sqrt(vecB.rows());
104 m_elSolver.constructSolution(m_displacement);
105 aitken(dispOldOld,dispOldGuess,dispOld,m_displacement);
109 gsInfo << numIter <<
": absRes " << absResNorm <<
", relRes " << absResNorm/initResNorm << std::endl;
112 elTime += clock.stop();
120 m_aleSolver.recoverState();
123 for (
size_t p = 0; p < m_nsSolver.aleInterface().patches.size(); ++p)
125 index_t pFlow = m_nsSolver.aleInterface().patches[p].second;
126 index_t pALE = m_nsSolver.aleInterface().patches[p].first;
127 m_nsSolver.assembler().patches().patch(pFlow).coefs() -= m_ALEdisplacment.patch(pALE).coefs();
128 m_nsSolver.mAssembler().patches().patch(pFlow).coefs() -= m_ALEdisplacment.patch(pALE).coefs();
132 m_aleSolver.constructSolution(m_ALEvelocity);
134 if (m_aleSolver.updateMesh() != -1)
137 m_aleSolver.constructSolution(m_ALEdisplacment);
138 for (
size_t p = 0; p < m_ALEvelocity.nPatches(); ++p)
139 m_ALEvelocity.patch(p).coefs() = (m_ALEdisplacment.patch(p).coefs() - m_ALEvelocity.patch(p).coefs()) / timeStep;
142 for (
size_t p = 0; p < m_nsSolver.aleInterface().patches.size(); ++p)
144 index_t pFlow = m_nsSolver.aleInterface().patches[p].second;
145 index_t pALE = m_nsSolver.aleInterface().patches[p].first;
146 m_nsSolver.assembler().patches().patch(pFlow).coefs() += m_ALEdisplacment.patch(pALE).coefs();
147 m_nsSolver.mAssembler().patches().patch(pFlow).coefs() += m_ALEdisplacment.patch(pALE).coefs();
150 aleTime += clock.stop();
157 m_nsSolver.recoverState();
161 for (
size_t p = 0; p < m_nsSolver.aleInterface().sidesA.size(); ++p)
163 index_t pFlow = m_nsSolver.aleInterface().sidesB[p].patch;
164 boxSide sFlow = m_nsSolver.aleInterface().sidesB[p].side();
165 index_t pALE = m_nsSolver.aleInterface().sidesA[p].patch;
166 boxSide sALE = m_nsSolver.aleInterface().sidesA[p].side();
167 m_nsSolver.assembler().setFixedDofs(pFlow,sFlow,m_ALEvelocity.patch(pALE).boundary(sALE)->coefs());
170 m_nsSolver.makeTimeStep(timeStep);
171 m_nsSolver.constructSolution(m_velocity,m_pressure);
173 nsTime += clock.stop();
180 if (m_options.getInt(
"Verbosity") != solver_verbosity::none && numIter > 1)
183 gsInfo <<
"Converged after " << numIter <<
" iters, absRes "
184 << absResNorm <<
", relRes " << absResNorm/initResNorm << std::endl;
186 gsInfo <<
"Terminated after " << numIter <<
" iters, absRes "
187 << absResNorm <<
", relRes " << absResNorm/initResNorm << std::endl;
194 void gsPartitionedFSI<T>::formVector(
const gsMultiPatch<T> & disp, gsMatrix<T> & vector)
196 index_t dim = disp.patch(0).parDim();
199 for (
size_t i = 0; i < m_aleSolver.interface().sidesA.size(); ++i)
201 index_t patch = m_aleSolver.interface().sidesA[i].patch;
202 boxSide side = m_aleSolver.interface().sidesA[i].side();
203 totalSize += disp.patch(patch).boundary(side)->coefs().rows();
206 vector.setZero(totalSize*dim,1);
208 for (
size_t i = 0; i < m_aleSolver.interface().sidesA.size(); ++i)
210 index_t patch = m_aleSolver.interface().sidesA[i].patch;
211 boxSide side = m_aleSolver.interface().sidesA[i].side();
212 index_t size = disp.patch(patch).boundary(side)->coefs().rows();
213 for (
index_t d = 0; d < dim;++d)
215 vector.middleRows(filledSize,size) = disp.patch(patch).boundary(side)->coefs().col(d);
222 void gsPartitionedFSI<T>::aitken(gsMultiPatch<T> & dispOO, gsMultiPatch<T> & dispOG,
223 gsMultiPatch<T> & dispO, gsMultiPatch<T> & dispN)
225 gsMatrix<> vecOO,vecOG,vecO,vecN;
226 formVector(dispOO,vecOO);
227 formVector(dispOG,vecOG);
228 formVector(dispO,vecO);
229 formVector(dispN,vecN);
231 gsMatrix<> vecTemp = vecN - vecO - vecOG + vecOO;
232 omega = -1*omega * ((vecOG - vecOO).transpose()*vecTemp)(0,0) /
233 (vecTemp.transpose()*vecTemp)(0,0);
235 for (
size_t p = 0; p < dispOO.nPatches(); ++p)
237 dispOO.patch(p).coefs() = dispO.patch(p).coefs();
238 dispOG.patch(p).coefs() = dispN.patch(p).coefs();
239 dispN.patch(p).coefs() = omega * dispN.patch(p).coefs() + (1-omega) * dispO.patch(p).coefs();
240 dispO.patch(p).coefs() = dispN.patch(p).coefs();
243 formVector(dispN,vecN);
244 absResNorm = ((vecN-vecO)*omega).norm()/sqrt(vecN.rows());
245 if (absResNorm < m_options.getReal(
"AbsTol") || absResNorm/initResNorm < m_options.getReal(
"RelTol"))
#define index_t
Definition: gsConfig.h:32
Provides isogeometric meshing and modelling routines.
Implementation of mesh deformation method for partitioned FSI solver.
Provides time integration for dynamical elasticity.
only essential output
Definition: gsBaseUtils.h:84
#define gsInfo
Definition: gsDebug.h:43
gsGenericStopwatch< WallClock > gsStopwatch
A stop-watch measuring real (wall) time.
Definition: gsStopwatch.h:160
Provides time integration for incompressible Navier-Stokes equations.