13 argsPtr =
new Foam::argList(argc,argv);
15 Info <<
"FsiFoam:Initialize: Error: Failed to create args object." << endl;
18 if (!argsPtr->checkRootCase()){
19 Info <<
"FsiFoam:Initialize: Error: Root case setup failed." << endl;
22 Foam::argList &args(*argsPtr);
23 runTimePtr =
new Foam::Time
25 Foam::Time::controlDictName,
30 !args.optionFound(
"noFunctionObjects")
33 Info <<
"FsiFoam:Initialize: Error: Failed to setup time object." << endl;
38 InitTransportProperties();
41 CreateStructuresFields();
42 ReadCouplingProperties();
43 CreateInterZoneInterpolators();
44 FindGlobalFaceZones();
47 CreateFSISurfaceMesh();
54 Foam::Time &runTime(*runTimePtr);
55 Info <<
"FsiFoam:Initialize: Create dynamic mesh for time = "
56 << runTime.timeName() << endl;
61 meshPtr = dynamicFvMesh::New(IOobject(dynamicFvMesh::defaultRegion,
64 IOobject::MUST_READ));
69 Foam::Time &runTime(*runTimePtr);
70 dynamicFvMesh &mesh = meshPtr();
71 Info <<
"FsiFoam:Initialize: Reading transportProperties" << endl;
72 transportPropertiesPtr =
new IOdictionary(IOobject(
"transportProperties",
82 Foam::Time &runTime(*runTimePtr);
83 dynamicFvMesh &fluidsMesh = meshPtr();
84 IOdictionary &transportProperties(*transportPropertiesPtr);
87 nuPtr =
new dimensionedScalar(transportProperties.lookup(
"nu"));
88 rhoFluidPtr =
new dimensionedScalar(transportProperties.lookup(
"rho"));
90 Info <<
"FsiFoam:CreateFluidFields: Reading field p" << endl;
95 pPtr =
new volScalarField(IOobject(
"p",
99 IOobject::AUTO_WRITE),
102 volScalarField &p(*pPtr);
104 Info <<
"FsiFoam:CreateFluidFields: Reading field U" << endl;
109 UPtr =
new volVectorField(IOobject(
"U",runTime.timeName(),fluidsMesh,
110 IOobject::MUST_READ,IOobject::AUTO_WRITE),fluidsMesh);
112 volVectorField &U = *UPtr;
115 Info <<
"FsiFoam:CreateFluidFields: Reading/calculating face flux field phi" << endl;
117 phiPtr =
new surfaceScalarField(IOobject(
"phi",runTime.timeName(),fluidsMesh,
118 IOobject::READ_IF_PRESENT,IOobject::AUTO_WRITE),
119 linearInterpolate(U) & fluidsMesh.Sf());
123 setRefCell(p, fluidsMesh.solutionDict().subDict(
"PISO"), pRefCell, pRefValue);
128 Foam::Time &runTime(*runTimePtr);
129 stressMeshPtr =
new fvMesh(IOobject(
"solid",runTime.timeName(),runTime,IOobject::MUST_READ));
130 return(stressMeshPtr != NULL);
134 Foam::Time &runTime(*runTimePtr);
135 fvMesh &structMesh(*stressMeshPtr);
137 Info <<
"FsiFoam:CreateStructuresFields: Reading incremental displacement field DU" << endl;
142 DUPtr =
new volVectorField(IOobject(
"DU",runTime.timeName(),structMesh,
143 IOobject::MUST_READ,IOobject::AUTO_WRITE),
146 volVectorField &DURef(*DUPtr);
150 gradDUPtr =
new volTensorField(fvc::grad(DURef));
151 volTensorField &gradDURef(*gradDUPtr);
153 UsolidPtr =
new volVectorField(IOobject(
"Usolid",runTime.timeName(),structMesh,
154 IOobject::READ_IF_PRESENT,IOobject::AUTO_WRITE),
158 Info <<
"FsiFoam:CreateStructuresFields: Reading incremental displacement field DV" << endl;
159 DVPtr =
new volVectorField(IOobject(
"DV",runTime.timeName(),structMesh,
160 IOobject::READ_IF_PRESENT,IOobject::AUTO_WRITE),
164 Info <<
"FsiFoam:CreateStructuresFields: Reading accumulated velocity field V" << endl;
165 VsPtr =
new volVectorField(IOobject(
"Vs",runTime.timeName(),structMesh,
166 IOobject::READ_IF_PRESENT,IOobject::AUTO_WRITE),
168 dimensionedVector(
"zero",dimVelocity,vector::zero));
171 Info <<
"FsiFoam:CreateStructuresFields: Reading accumulated stress field sigma" << endl;
172 sigmaPtr =
new volSymmTensorField(IOobject(
"sigma",runTime.timeName(),structMesh,
173 IOobject::READ_IF_PRESENT,IOobject::AUTO_WRITE),
175 dimensionedSymmTensor(
"zero",dimForce/dimArea,symmTensor::zero));
176 volSymmTensorField &sigmaref(*sigmaPtr);
179 Info <<
"FsiFoam:CreateStructuresFields: Reading incremental stress field DSigma" << endl;
180 DSigmaPtr =
new volSymmTensorField(IOobject(
"DSigma",runTime.timeName(),structMesh,
181 IOobject::READ_IF_PRESENT,IOobject::AUTO_WRITE),
183 dimensionedSymmTensor(
"zero",dimForce/dimArea,symmTensor::zero));
186 rheologyPtr =
new constitutiveModel(sigmaref,DURef);
188 constitutiveModel &rheology(*rheologyPtr);
192 rhoPtr =
new volScalarField(rheology.rho());
193 muPtr =
new volScalarField(rheology.mu());
194 lambdaPtr =
new volScalarField(rheology.lambda());
196 FPtr =
new volTensorField(I + gradDURef.T());
197 volTensorField &FRef(*FPtr);
198 DFPtr =
new volTensorField(FRef - I);
199 JPtr =
new volScalarField(det(FRef));
201 solidDdtSchemePtr =
new word(structMesh.schemesDict().ddtScheme(
"ddt("+DURef.name()+
')'));
205 Foam::argList &args(*argsPtr);
206 Foam::Time &runTime(*runTimePtr);
207 dynamicFvMesh &fluidMesh(meshPtr());
208 fvMesh &structMesh(*stressMeshPtr);
210 Info <<
"FsiFoam:ReadCouplingProperties: Reading coupling properties" << endl;
212 couplingPropertiesPtr =
new IOdictionary(IOobject(
"couplingProperties",runTime.constant(),
213 fluidMesh,IOobject::MUST_READ,IOobject::NO_WRITE));
214 IOdictionary &couplingProperties(*couplingPropertiesPtr);
216 solidPatchName = word(couplingProperties.lookup(
"solidPatch"));
217 solidPatchID = structMesh.boundaryMesh().findPatchID(solidPatchName);
219 if (solidPatchID < 0)
221 FatalErrorIn(args.executable())
222 <<
"FsiFoam:ReadCouplingProperties: Problem with finding solid patch"
223 << abort(FatalError);
226 solidZoneName = word(couplingProperties.lookup(
"solidZone"));
230 structMesh.faceZones().findZoneID(solidZoneName);
234 FatalErrorIn(args.executable())
235 <<
"FsiFoam:ReadCouplingProperties: Problem with finding solid zone"
236 << abort(FatalError);
239 fluidPatchName = word(couplingProperties.lookup(
"fluidPatch"));
240 fluidPatchID = fluidMesh.boundaryMesh().findPatchID(fluidPatchName);
243 if (fluidPatchID < 0)
245 FatalErrorIn(args.executable())
246 <<
"FsiFoam:ReadCouplingProperties: Problem with finding fluid patch"
247 << abort(FatalError);
250 fluidZoneName = word(couplingProperties.lookup(
"fluidZone"));
251 fluidZoneID = fluidMesh.faceZones().findZoneID(fluidZoneName);
254 FatalErrorIn(args.executable())
255 <<
"FsiFoam:ReadCouplingProperties: Problem with finding fluid zone"
256 << abort(FatalError);
259 feMotionSolver = fluidMesh.objectRegistry::foundObject<tetPointVectorField>(
"motionU");
260 fvMotionSolver = fluidMesh.objectRegistry::foundObject<pointVectorField>(
"pointMotionU");
268 Info <<
"FsiFoam:ReadCouplingProperties:Solid patch ID: " << solidPatchID << endl;
269 volVectorField &DURef(*DUPtr);
272 DURef.boundaryField()[solidPatchID].type()
273 != solidTractionFvPatchVectorField::typeName
277 FatalErrorIn(args.executable())
278 <<
"FsiFoam:ReadCouplingProperties: Boundary condition on " << DURef.name()
280 << DURef.boundaryField()[solidPatchID].type()
281 <<
"for fluid -solid interface patch, instead "
282 << solidTractionFvPatchVectorField::typeName
284 << abort(FatalError);
293 accumulatedFluidInterfaceDisplacementHeaderPtr =
new IOobject(
"accumulatedFluidInterfaceDisplacement",
296 IOobject::MUST_READ);
297 IOobject &accumulatedFluidInterfaceDisplacementHeader(*accumulatedFluidInterfaceDisplacementHeaderPtr);
301 if(accumulatedFluidInterfaceDisplacementHeader.headerOk())
303 Pout <<
"FsiFoam:ReadCouplingProperties: Reading accumulated fluid interface displacement" << endl;
305 accumulatedFluidInterfaceDisplacementPtr =
310 "accumulatedFluidInterfaceDisplacement",
320 accumulatedFluidInterfaceDisplacementPtr =
325 "accumulatedFluidInterfaceDisplacement",
334 fluidMesh.boundaryMesh()[fluidPatchID].nPoints(),
353 dynamicFvMesh &fluidMesh = meshPtr();
354 fvMesh &structMesh(*stressMeshPtr);
356 if(!interpolatorFluidSolidPtr || !interpolatorSolidFluidPtr)
358 deleteDemandDrivenData(interpolatorFluidSolidPtr);
359 deleteDemandDrivenData(interpolatorSolidFluidPtr);
361 Info <<
"FsiFoam:CreateInterZoneInterpolators: Create fluid-to-solid and solid-to-fluid interpolators" << endl;
363 interpolatorFluidSolidPtr =
new zoneToZoneInterpolation
365 fluidMesh.faceZones()[fluidZoneID](),
366 structMesh.faceZones()[solidZoneID](),
367 intersection::VISIBLE
370 interpolatorSolidFluidPtr =
new zoneToZoneInterpolation
372 structMesh.faceZones()[solidZoneID](),
373 fluidMesh.faceZones()[fluidZoneID](),
374 intersection::VISIBLE
377 Info <<
"FsiFoam:CreateInterZoneInterpolators: Check fluid-to-solid and solid-to-fluid interpolators" << endl;
380 vectorField fluidPatchFaceCentres =
381 vectorField(fluidMesh.boundaryMesh()[fluidPatchID].faceCentres());
383 vectorField fluidZoneFaceCentres
385 fluidMesh.faceZones()[fluidZoneID].size(),
390 const label fluidPatchStart =
391 fluidMesh.boundaryMesh()[fluidPatchID].start();
393 forAll (fluidPatchFaceCentres, i)
397 fluidMesh.faceZones()[fluidZoneID].whichFace(fluidPatchStart + i)
399 fluidPatchFaceCentres[i];
403 reduce(fluidZoneFaceCentres, sumOp<vectorField>());
405 vectorField solidZoneFaceCentres =
406 interpolatorFluidSolidPtr->faceInterpolate
411 vectorField solidPatchFaceCentres
413 structMesh.boundaryMesh()[solidPatchID].size(),
417 const label solidPatchStart =
418 structMesh.boundaryMesh()[solidPatchID].start();
420 forAll(solidPatchFaceCentres, i)
422 solidPatchFaceCentres[i] =
425 structMesh.faceZones()[solidZoneID]
426 .whichFace(solidPatchStart + i)
430 scalar maxDist = gMax
434 solidPatchFaceCentres
435 - structMesh.boundaryMesh()[solidPatchID].faceCentres()
439 Info <<
"FsiFoam:CreateInterZoneInterpolators: Fluid-to-solid face interpolation error: " << maxDist
446 vectorField solidPatchFaceCentres =
447 vectorField(structMesh.boundaryMesh()[solidPatchID].faceCentres());
449 vectorField solidZoneFaceCentres
451 structMesh.faceZones()[solidZoneID].size(),
455 const label solidPatchStart =
456 structMesh.boundaryMesh()[solidPatchID].start();
458 forAll (solidPatchFaceCentres, i)
462 structMesh.faceZones()[solidZoneID]
463 .whichFace(solidPatchStart + i)
465 solidPatchFaceCentres[i];
469 reduce(solidZoneFaceCentres, sumOp<vectorField>());
471 vectorField fluidZoneFaceCentres =
472 interpolatorSolidFluidPtr->faceInterpolate
477 vectorField fluidPatchFaceCentres
479 fluidMesh.boundaryMesh()[fluidPatchID].size(),
483 const label fluidPatchStart =
484 fluidMesh.boundaryMesh()[fluidPatchID].start();
486 forAll(fluidPatchFaceCentres, i)
488 fluidPatchFaceCentres[i] =
491 fluidMesh.faceZones()[fluidZoneID]
492 .whichFace(fluidPatchStart + i)
496 scalar maxDist = gMax
500 fluidPatchFaceCentres
501 - fluidMesh.boundaryMesh()[fluidPatchID].faceCentres()
505 Info <<
"FsiFoam:CreateInterZoneInterpolators: Solid-to-fluid face interpolation error: " << maxDist
517 fvMesh &structMesh(*stressMeshPtr);
518 Foam::argList &args = *argsPtr;
521 SLList<label> globalFaceZonesSet;
523 const faceZoneMesh& faceZones = structMesh.faceZones();
525 forAll(faceZones, zoneI)
527 const faceZone& curFaceZone = faceZones[zoneI];
529 forAll(curFaceZone, faceI)
532 if (curFaceZone[faceI] >= structMesh.nFaces())
534 globalFaceZonesSet.insert(zoneI);
540 globalFaceZones = labelList(globalFaceZonesSet);
542 globalToLocalFaceZonePointMap.resize(globalFaceZones.size());
544 forAll(globalFaceZones, zoneI)
546 label curZoneID = globalFaceZones[zoneI];
547 labelList curMap(structMesh.faceZones()[curZoneID]().nPoints(), -1);
548 vectorField fzGlobalPoints =
549 structMesh.faceZones()[curZoneID]().localPoints();
552 if(!Pstream::master())
554 fzGlobalPoints *= 0.0;
558 reduce(fzGlobalPoints, sumOp<vectorField>());
563 const vectorField& fzLocalPoints =
564 structMesh.faceZones()[curZoneID]().localPoints();
565 const edgeList& fzLocalEdges =
566 structMesh.faceZones()[curZoneID]().edges();
567 const labelListList& fzPointEdges =
568 structMesh.faceZones()[curZoneID]().pointEdges();
569 scalarField minEdgeLength(fzLocalPoints.size(), GREAT);
571 forAll(minEdgeLength, pI)
573 const labelList& curPointEdges = fzPointEdges[pI];
574 forAll(curPointEdges, eI)
576 scalar Le = fzLocalEdges[curPointEdges[eI]].mag(fzLocalPoints);
577 if (Le < minEdgeLength[pI])
579 minEdgeLength[pI] = Le;
584 forAll(fzGlobalPoints, globalPointI)
588 forAll(fzLocalPoints, procPointI)
593 fzLocalPoints[procPointI]
594 - fzGlobalPoints[globalPointI]
602 if (curDist < 1e-4*minEdgeLength[procPointI])
604 curMap[globalPointI] = procPointI;
615 forAll(curMap, globalPointI)
617 if (curMap[globalPointI] == -1)
619 FatalErrorIn(args.executable())
620 <<
"FsiFoam:FindGlobalFaceZones: local to global face zone point map is not correct"
621 << abort(FatalError);
625 globalToLocalFaceZonePointMap[zoneI] = curMap;
631 dynamicFvMesh &fluidMesh(meshPtr());
632 dictionary &piso(fluidMesh.solutionDict().subDict(
"PISO"));
634 nCorr = readInt(piso.lookup(
"nCorrectors"));
635 nNonOrthCorr = piso.lookupOrDefault<
int>(
"nNonOrthogonalCorrectors", 0);
636 momentumPredictor = piso.lookupOrDefault<Switch>(
"momentumPredictor",
true);
637 transonic = piso.lookupOrDefault<Switch>(
"transonic",
false);
638 nOuterCorr = piso.lookupOrDefault<
int>(
"nOuterCorrectors", 1);
644 IOdictionary &couplingProperties(*couplingPropertiesPtr);
648 if (couplingProperties.found(
"couplingScheme"))
650 couplingScheme = word(couplingProperties.lookup(
"couplingScheme"));
653 (couplingScheme ==
"IQN-ILS")
654 || (couplingScheme ==
"Aitken")
655 || (couplingScheme ==
"FixedRelaxation")
656 || (couplingScheme ==
"NonIterative")
659 Info<<
"FsiFoam:ReadFSIControl: Selecting coupling scheme " << couplingScheme << endl;
666 ) <<
"couplingScheme: " << couplingScheme
667 <<
" is not a valid choice. "
668 <<
"Options are: IQN-ILS, Aitken, FixedRelaxation"
669 << abort(FatalError);
673 interfaceDeformationLimit =
674 scalar(readScalar(couplingProperties.lookup(
"interfaceDeformationLimit")));
691 fsiRelaxationFactorMin = scalar(readScalar(couplingProperties.lookup(
"fsiRelaxationFactor")));
692 fsiRelaxationFactor = fsiRelaxationFactorMin;
693 outerCorrTolerance = scalar(readScalar(couplingProperties.lookup(
"outerCorrTolerance")));
694 Info <<
"FsiFoam:ReadFSIControl: outerCorrTolerance = " << outerCorrTolerance << endl;
695 fsi = Switch(couplingProperties.lookup(
"fsi"));
697 Info <<
"FsiFoam:ReadFSIControl: FSI IS ENABLED." << endl;
699 Info <<
"FsiFoam:ReadFSIControl: FSI IS DISABLED." << endl;
704 Foam::argList &args(this->ArgList());
705 Foam::Time &runTime(this->RunTime());
706 dynamicFvMesh &fluidsMesh(this->FluidMesh());
708 dimensionedScalar &nu(this->nu());
709 dimensionedScalar &rhoFluid(this->rhoFluid());
710 volScalarField &p(this->p());
711 volVectorField &U(this->U());
712 surfaceScalarField &phi(this->phi());
717 fvMesh &structuresMesh(this->StructuresMesh());
720 volVectorField &DU(this->DU());
721 volTensorField &gradDU(this->gradDU());
722 volVectorField &Usolid(this->Usolid());
723 volVectorField &DV(this->DV());
724 volVectorField &Vs(this->Vs());
725 volSymmTensorField &sigma(this->sigma());
726 volSymmTensorField &DSigma(this->DSigma());
728 volScalarField &rho(this->rhoSolid());
729 volScalarField &mu(this->mu());
730 volScalarField &lambda(this->lambda());
731 volTensorField &F(this->F());
732 volTensorField &DF(this->DF());
733 volScalarField &J(this->J());
734 word &solidDdtScheme(this->SolidDdtScheme());
740 label solidPatchID(this->SolidPatchID());
742 label fluidPatchID(this->FluidPatchID());
744 label fluidZoneID(this->FluidZoneID());
745 label solidZoneID(this->SolidZoneID());
747 bool feMotionSolver(this->FEMotion());
748 bool fvMotionSolver(this->FVMotion());
749 vectorField &accumulatedFluidInterfaceDisplacement(this->AccumulatedFluidInterfaceDisplacements());
751 Info <<
"FsiFoam:Step: accumulatedFluidInterfaceDisplacement = " << endl;
752 Info << accumulatedFluidInterfaceDisplacement << endl;
754 solidTractionFvPatchVectorField &tForce(this->tForce());
756 zoneToZoneInterpolation &interpolatorFluidSolid(this->interpFluidSolid());
757 zoneToZoneInterpolation &interpolatorSolidFluid(this->interpSolidFluid());
759 scalar &sumLocalContErr(this->LocalContErr());
760 scalar &globalContErr(this->GlobalContErr());
761 scalar &cumulativeContErr(this->CumulativeContErr());
763 labelList &globalFaceZones(this->GlobalFaceZones());
764 labelListList &globalToLocalFaceZonePointMap(this->GlobalToLocalFaceZonePointMap());
775 this->ReadPISOControls();
776 this->ReadFSIControls();
777 word couplingScheme(this->CouplingScheme());
779 scalar &fsiRelaxationFactor(this->FSIRelaxationFactor());
781 Switch fsi(this->FSIEnabled());
782 int &nCorrPISO(this->NCorrPISO());
783 int &nNonOrthCorr(this->NNonOrthCorr());
784 scalar &interfaceDeformationLimit(this->InterfaceDeformationLimit());
785 scalar &outerCorrTolerance(this->OuterCorrTolerance());
786 int &nOuterCorr(this->NOuterCorr());
792 pointMesh StructuresPointMesh(structuresMesh);
794 pointPatchInterpolation patchPointInterpolator(structuresMesh);
801 StructuresPointMesh.boundary().size(),
802 calculatedFvPatchVectorField::typeName
807 forAll(DU.boundaryField().types(), patchI)
811 DU.boundaryField().types()[patchI]
812 == fixedValueFvPatchVectorField::typeName
815 types[patchI] = fixedValueFvPatchVectorField::typeName;
819 pointVectorField pointDU
828 dimensionedVector(
"zero", dimLength, vector::zero),
832 vectorField fluidPatchPointsDispl
834 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
838 vectorField fluidPatchPointsDisplOld
840 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
844 vectorField solidPatchPointsDispl
846 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
850 vectorField fsiResidual
852 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
856 vectorField fsiResidualOld
858 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
862 vectorField solidPatchTraction
864 structuresMesh.boundary()[solidPatchID].size(),
868 scalarField solidPatchPressure
870 structuresMesh.boundary()[solidPatchID].size(),
874 scalar initialFsiResidualNorm = 0;
875 scalar fsiResidualNorm = 0;
883 Info <<
"\nTime = " << runTime.timeName()
884 <<
", iteration: " << outerCorr << endl;
886 if (outerCorr < 3 || couplingScheme ==
"FixedRelaxation")
888 Info <<
"FsiFoam:Step: Current fsi under-relaxation factor: "
889 << fsiRelaxationFactor << endl;
891 fluidPatchPointsDisplOld = fluidPatchPointsDispl;
893 fluidPatchPointsDispl += fsiRelaxationFactor*fsiResidual;
897 if (couplingScheme ==
"Aitken")
899 fsiRelaxationFactor =
905 &(fsiResidual - fsiResidualOld)
910 (fsiResidual - fsiResidualOld)
911 &(fsiResidual - fsiResidualOld)
916 fsiRelaxationFactor = mag(fsiRelaxationFactor);
918 Info <<
"FsiFoam:Step: Current fsi under-relaxation factor (Aitken): "
919 << fsiRelaxationFactor << endl;
921 fluidPatchPointsDisplOld = fluidPatchPointsDispl;
923 fluidPatchPointsDispl +=
924 fsiRelaxationFactor*fsiResidual;
935 const vectorField& n =
936 fluidsMesh.boundaryMesh()[fluidPatchID].pointNormals();
938 primitivePatchInterpolation patchInterpolator
940 fluidsMesh.boundaryMesh()[fluidPatchID]
943 scalarField pointDeltaCoeffs =
944 patchInterpolator.faceToPointInterpolate
946 fluidsMesh.boundary()[fluidPatchID].deltaCoeffs()
956 accumulatedFluidInterfaceDisplacement
957 + fluidPatchPointsDispl
958 - fluidPatchPointsDisplOld
964 Info <<
"FsiFoam:Step: Maximal accumulated displacement of interface points: "
967 if(delta < interfaceDeformationLimit)
971 Info <<
"FsiFoam:Step: Moving only interface points..." << endl;
973 pointField newPoints = fluidsMesh.allPoints();
975 const labelList& meshPoints =
976 fluidsMesh.boundaryMesh()[fluidPatchID].meshPoints();
978 forAll (fluidPatchPointsDispl, pointI)
982 newPoints[meshPoints[pointI]] +=
983 fluidPatchPointsDispl[pointI]
984 - fluidPatchPointsDisplOld[pointI];
987 twoDPointCorrector twoDCorrector(fluidsMesh);
989 twoDCorrector.correctPoints(newPoints);
991 fluidsMesh.movePoints(newPoints);
994 accumulatedFluidInterfaceDisplacement +=
995 fluidPatchPointsDispl
996 - fluidPatchPointsDisplOld;
1002 Info <<
"FsiFoam:Step: Moving the whole mesh .... " << endl;
1004 pointField newPoints = fluidsMesh.allPoints();
1006 const labelList& meshPoints =
1007 fluidsMesh.boundaryMesh()[fluidPatchID].meshPoints();
1009 forAll (accumulatedFluidInterfaceDisplacement, pointI)
1013 newPoints[meshPoints[pointI]] -=
1014 accumulatedFluidInterfaceDisplacement[pointI];
1017 twoDPointCorrector twoDCorrector(fluidsMesh);
1019 twoDCorrector.correctPoints(newPoints);
1021 fluidsMesh.movePoints(newPoints);
1023 accumulatedFluidInterfaceDisplacement +=
1024 fluidPatchPointsDispl
1025 - fluidPatchPointsDisplOld;
1030 tetPointVectorField& motionU =
1031 const_cast<tetPointVectorField&
>
1033 fluidsMesh.objectRegistry::
lookupObject<tetPointVectorField>
1039 fixedValueTetPolyPatchVectorField& motionUFluidPatch =
1040 refCast<fixedValueTetPolyPatchVectorField>
1042 motionU.boundaryField()[fluidPatchID]
1045 tetPolyPatchInterpolation tppi
1047 refCast<const faceTetPolyPatch>(motionUFluidPatch.patch())
1050 motionUFluidPatch ==
1051 tppi.pointToPointInterpolate
1053 accumulatedFluidInterfaceDisplacement
1054 /runTime.deltaT().value()
1057 else if (fvMotionSolver)
1059 pointVectorField& motionU =
1060 const_cast<pointVectorField&
>
1062 fluidsMesh.objectRegistry::
lookupObject<pointVectorField>
1068 fixedValuePointPatchVectorField& motionUFluidPatch =
1069 refCast<fixedValuePointPatchVectorField>
1071 motionU.boundaryField()[fluidPatchID]
1074 motionUFluidPatch ==
1075 accumulatedFluidInterfaceDisplacement
1076 /runTime.deltaT().value();
1080 FatalErrorIn(args.executable())
1081 <<
"FsiFoam:Step: Problem with mesh motion solver selection"
1082 << abort(FatalError);
1085 fluidsMesh.update();
1087 accumulatedFluidInterfaceDisplacement = vector::zero;
1094 if(fluidsMesh.moving())
1097 phi -= fvc::meshPhi(U);
1103 scalar meanCoNum = 0.0;
1104 scalar velMag = 0.0;
1106 if (fluidsMesh.nInternalFaces())
1108 surfaceScalarField magPhi = mag(phi);
1110 surfaceScalarField SfUfbyDelta =
1111 fluidsMesh.surfaceInterpolation::deltaCoeffs()*magPhi;
1113 const scalar deltaT = runTime.deltaT().value();
1115 CoNum = max(SfUfbyDelta/fluidsMesh.magSf()).value()*deltaT;
1117 meanCoNum = (sum(SfUfbyDelta)/sum(fluidsMesh.magSf())).value()*deltaT;
1119 velMag = max(magPhi/fluidsMesh.magSf()).value();
1122 Info<<
"FsiFoam:Step: Courant Number mean: " << meanCoNum
1123 <<
" max: " << CoNum
1124 <<
" velocity magnitude: " << velMag
1131 - fvm::laplacian(nu, U)
1134 solve(UEqn == -fvc::grad(p));
1137 volScalarField rUA = 1.0/UEqn.A();
1139 for (
int corr=0; corr<nCorrPISO; corr++)
1142 phi = (fvc::interpolate(U) & fluidsMesh.Sf());
1144 adjustPhi(phi, U, p);
1146 for (
int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
1150 fvm::laplacian(rUA, p)
1154 pEqn.setReference(pRefCell, pRefValue);
1157 if (nonOrth == nNonOrthCorr)
1165 volScalarField contErr = fvc::div(phi);
1167 sumLocalContErr = runTime.deltaT().value()*
1168 mag(contErr)().weightedAverage(fluidsMesh.V()).value();
1170 globalContErr = runTime.deltaT().value()*
1171 contErr.weightedAverage(fluidsMesh.V()).value();
1173 cumulativeContErr += globalContErr;
1175 Info<<
"FsiFoam:Step: time step continuity errors : sum local = " << sumLocalContErr
1176 <<
", global = " << globalContErr
1177 <<
", cumulative = " << cumulativeContErr
1181 U -= rUA*fvc::grad(p);
1182 U.correctBoundaryConditions();
1189 Info <<
"FsiFoam:Step: Setting traction on solid patch" << endl;
1197 vectorField fluidPatchTraction =
1198 -rhoFluid.value()*nu.value()
1199 *U.boundaryField()[fluidPatchID].snGrad();
1203 scalarField fluidPatchPressure =
1204 rhoFluid.value()*p.boundaryField()[fluidPatchID];
1208 vectorField fluidZoneTraction
1210 fluidsMesh.faceZones()[fluidZoneID].size(),
1216 const label fluidPatchStart =
1217 fluidsMesh.boundaryMesh()[fluidPatchID].start();
1219 forAll(fluidPatchTraction, i)
1223 fluidsMesh.faceZones()[fluidZoneID].whichFace(fluidPatchStart + i)
1225 fluidPatchTraction[i];
1229 reduce(fluidZoneTraction, sumOp<vectorField>());
1232 scalarField fluidZonePressure
1234 fluidsMesh.faceZones()[fluidZoneID].size(),
1238 forAll(fluidPatchPressure, i)
1242 fluidsMesh.faceZones()[fluidZoneID].whichFace(fluidPatchStart + i)
1244 fluidPatchPressure[i];
1248 reduce(fluidZonePressure, sumOp<scalarField>());
1250 vectorField solidZoneTraction =
1251 interpolatorFluidSolid.faceInterpolate
1258 scalarField solidZonePressure =
1259 interpolatorFluidSolid.faceInterpolate
1266 const label solidPatchStart =
1267 structuresMesh.boundaryMesh()[solidPatchID].start();
1269 forAll(solidPatchTraction, i)
1271 solidPatchTraction[i] =
1274 structuresMesh.faceZones()[solidZoneID]
1275 .whichFace(solidPatchStart + i)
1279 forAll(solidPatchPressure, i)
1281 solidPatchPressure[i] =
1284 structuresMesh.faceZones()[solidZoneID]
1285 .whichFace(solidPatchStart + i)
1291 tForce.traction() = solidPatchTraction;
1292 tForce.pressure() = solidPatchPressure;
1295 vector totalTractionForce =
1299 *structuresMesh.magSf().boundaryField()[solidPatchID]
1302 Info <<
"FsiFoam:Step: Total traction force = "
1303 << totalTractionForce << endl;
1309 if (solidDdtScheme == fv::EulerDdtScheme<vector>::typeName)
1311 Info <<
"FsiFoam:Step: Solve Solid: Euler" << endl;
1314 const dictionary& stressControl =
1315 structuresMesh.solutionDict().subDict(
"solidMechanics");
1317 int nCorrStruct(readInt(stressControl.lookup(
"nCorrectors")));
1318 scalar convergenceTolerance(readScalar(stressControl.lookup(
"DU")));
1322 lduMatrix::solverPerformance solverPerf;
1323 scalar initialResidual = 0;
1325 lduMatrix::debug = 0;
1328 dimensionedScalar Cn(
"Cn", dimless/dimTime, 1.0/runTime.deltaT().value());
1329 dimensionedScalar Co(
"Co", dimless/dimTime, 1.0/runTime.deltaT().value());
1335 fvVectorMatrix DUEqn
1338 - Co*rho*DV.oldTime()
1340 fvm::laplacian(2*mu + lambda, DU,
"laplacian(DDU,DU)")
1341 - fvc::laplacian(mu + lambda, DU,
"laplacian(DDU,DU)")
1345 + lambda*(I*tr(gradDU))
1346 + mu*(gradDU&gradDU.T())
1347 + 0.5*lambda*(I*tr(gradDU & gradDU.T()))
1349 + (DSigma & DF.T()),
1354 solverPerf = DUEqn.solve();
1360 initialResidual = solverPerf.initialResidual();
1363 gradDU = fvc::grad(DU);
1369 volSymmTensorField Depsilon = symm(gradDU)
1370 + 0.5*symm(gradDU & gradDU.T());
1372 DSigma = 2*mu*Depsilon + I*(lambda*tr(Depsilon));
1377 solverPerf.initialResidual() > convergenceTolerance
1378 && ++iCorr < nCorrStruct
1381 Info <<
"FsiFoam:Step: Solving for " << DU.name()
1382 <<
", Initial residual = " << initialResidual
1383 <<
", Final residual = " << solverPerf.initialResidual()
1384 <<
", No outer iterations " << iCorr << endl;
1388 lduMatrix::debug = 1;
1391 else if (solidDdtScheme == fv::backwardDdtScheme<vector>::typeName)
1393 Info <<
"FsiFoam:Step: Solve Solid: Backward" << endl;
1398 const dictionary& stressControl =
1399 structuresMesh.solutionDict().subDict(
"solidMechanics");
1401 int nCorrStruct(readInt(stressControl.lookup(
"nCorrectors")));
1402 scalar convergenceTolerance(readScalar(stressControl.lookup(
"DU")));
1405 lduMatrix::solverPerformance solverPerf;
1406 scalar initialResidual = 0;
1408 lduMatrix::debug = 0;
1411 dimensionedScalar Cn(
"Cn", dimless/dimTime, 0.0);
1412 dimensionedScalar Co(
"Co", dimless/dimTime, 0.0);
1413 dimensionedScalar Coo(
"Coo", dimless/dimTime, 0.0);
1415 scalar deltaT = runTime.deltaT().value();
1416 scalar deltaT0 = runTime.deltaT0().value();
1418 Cn.value() = 1 + deltaT/(deltaT + deltaT0);
1419 Coo.value() = deltaT*deltaT/(deltaT0*(deltaT + deltaT0));
1420 Co.value() = Cn.value() + Coo.value();
1422 if(runTime.timeIndex() == 1)
1429 Cn.value() /= deltaT;
1430 Co.value() /= deltaT;
1431 Coo.value() /= deltaT;
1454 fvVectorMatrix DUEqn
1457 - Co*rho*DV.oldTime()
1458 + Coo*rho*DV.oldTime().oldTime()
1460 fvm::laplacian(2*mu + lambda, DU,
"laplacian(DDU,DU)")
1461 - fvc::laplacian(mu + lambda, DU,
"laplacian(DDU,DU)")
1465 + lambda*(I*tr(gradDU))
1466 + mu*(gradDU&gradDU.T())
1467 + 0.5*lambda*(I*tr(gradDU & gradDU.T()))
1469 + (DSigma & DF.T()),
1474 solverPerf = DUEqn.solve();
1480 initialResidual = solverPerf.initialResidual();
1483 gradDU = fvc::grad(DU);
1489 volSymmTensorField Depsilon = symm(gradDU)
1490 + 0.5*symm(gradDU & gradDU.T());
1492 DSigma = 2*mu*Depsilon + I*(lambda*tr(Depsilon));
1502 solverPerf.initialResidual() > convergenceTolerance
1503 && ++iCorr < nCorrStruct
1506 Info <<
"FsiFoam:Step: Solving for " << DU.name()
1507 <<
", Initial residual = " << initialResidual
1508 <<
", Final residual = " << solverPerf.initialResidual()
1509 <<
", No outer iterations " << iCorr << endl;
1513 lduMatrix::debug = 1;
1518 FatalErrorIn(args.executable())
1519 <<
"FsiFoam:Step: Wrong temporal (ddt) scheme for solid solver. "
1520 <<
"Possible schemes are: "
1521 << fv::EulerDdtScheme<vector>::typeName <<
" and "
1522 << fv::backwardDdtScheme<vector>::typeName
1523 << abort(FatalError);
1528 const vectorField& solidPatchDisplacement =
1529 DU.boundaryField()[solidPatchID];
1531 vectorField solidZoneDisplacement
1533 structuresMesh.faceZones()[solidZoneID]().size(),
1537 const label solidPatchStart =
1538 structuresMesh.boundaryMesh()[solidPatchID].start();
1540 forAll(solidPatchDisplacement, i)
1542 solidZoneDisplacement
1544 structuresMesh.faceZones()[solidZoneID]
1545 .whichFace(solidPatchStart + i)
1547 solidPatchDisplacement[i];
1551 reduce(solidZoneDisplacement, sumOp<vectorField>());
1553 vectorField fluidZoneDisplacement =
1554 interpolatorSolidFluid.faceInterpolate
1556 solidZoneDisplacement
1559 vectorField fluidPatchDisplacement
1561 fluidsMesh.boundary()[fluidPatchID].size(),
1565 const label fluidPatchStart =
1566 fluidsMesh.boundaryMesh()[fluidPatchID].start();
1568 forAll(fluidPatchDisplacement, i)
1570 fluidPatchDisplacement[i] =
1571 fluidZoneDisplacement
1573 fluidsMesh.faceZones()[fluidZoneID].whichFace(fluidPatchStart + i)
1577 primitivePatchInterpolation fluidPatchInterpolator
1579 fluidsMesh.boundaryMesh()[fluidPatchID]
1582 solidPatchPointsDispl =
1583 fluidPatchInterpolator.faceToPointInterpolate
1585 fluidPatchDisplacement
1588 fsiResidualOld = fsiResidual;
1590 fsiResidual = solidPatchPointsDispl - fluidPatchPointsDispl;
1593 Info <<
"FsiFoam:Step: solidPatchPointsDispl = " << endl;
1594 Info << solidPatchPointsDispl << endl;
1595 Info <<
"FsiFoam:Step: fluidPatchPointsDispl = " << endl;
1596 Info << fluidPatchPointsDispl << endl;
1608 fsiResidualNorm = ::sqrt(gSum(magSqr(fsiResidual)));
1612 initialFsiResidualNorm = fsiResidualNorm;
1615 fsiResidualNorm /= initialFsiResidualNorm + SMALL;
1617 Info <<
"FsiFoam:Step: Current fsi residual norm: " << fsiResidualNorm << endl;
1622 (fsiResidualNorm > outerCorrTolerance)
1623 && (outerCorr < nOuterCorr)
1630 Info <<
"FsiFoam:Step: Rotating fields" << endl;
1649 sigma = 1/J * symm(F & sigma & F.T());
1655 if(min(J.internalField()) > 0)
1657 Info <<
"FsiFoam:Step: Moving mesh using least squares interpolation" << endl;
1659 leastSquaresVolPointInterpolation pointInterpolation(structuresMesh);
1662 pointMesh pMesh(structuresMesh);
1666 pMesh.boundary().size(),
1667 calculatedFvPatchVectorField::typeName
1670 pointVectorField pointDU
1679 dimensionedVector(
"zero", dimLength, vector::zero),
1683 pointInterpolation.interpolate(DU, pointDU);
1685 const vectorField& pointDUI =
1686 pointDU.internalField();
1689 vectorField newPoints = structuresMesh.allPoints();
1691 forAll (pointDUI, pointI)
1693 newPoints[pointI] += pointDUI[pointI];
1698 forAll(structuresMesh.boundaryMesh(), patchI)
1700 if (isA<symmetryPolyPatch>(structuresMesh.boundaryMesh()[patchI]))
1702 const labelList& meshPoints =
1703 structuresMesh.boundaryMesh()[patchI].meshPoints();
1706 gAverage(structuresMesh.boundaryMesh()[patchI].pointNormals());
1712 if (mag(avgN&i) > 0.95)
1714 forAll(meshPoints, pI)
1716 newPoints[meshPoints[pI]].x() = 0;
1719 else if (mag(avgN&j) > 0.95)
1721 forAll(meshPoints, pI)
1723 newPoints[meshPoints[pI]].y() = 0;
1726 else if (mag(avgN&k) > 0.95)
1728 forAll(meshPoints, pI)
1730 newPoints[meshPoints[pI]].z() = 0;
1737 forAll(globalFaceZones, zoneI)
1739 const label curZoneID = globalFaceZones[zoneI];
1741 const labelList& curMap =
1742 globalToLocalFaceZonePointMap[zoneI];
1744 const labelList& curZoneMeshPoints =
1745 structuresMesh.faceZones()[curZoneID]().meshPoints();
1747 vectorField curGlobalZonePointDispl
1749 curZoneMeshPoints.size(),
1755 scalarField pointNumProcs(curZoneMeshPoints.size(), 0);
1757 forAll(curGlobalZonePointDispl, globalPointI)
1759 label localPoint = curMap[globalPointI];
1761 if(curZoneMeshPoints[localPoint] < structuresMesh.nPoints())
1763 label procPoint = curZoneMeshPoints[localPoint];
1765 curGlobalZonePointDispl[globalPointI] = pointDUI[procPoint];
1767 pointNumProcs[globalPointI] = 1;
1771 if (Pstream::parRun())
1773 reduce(curGlobalZonePointDispl, sumOp<vectorField>());
1774 reduce(pointNumProcs, sumOp<scalarField>());
1777 curGlobalZonePointDispl /= pointNumProcs;
1784 vectorField curZonePointDispl
1786 curZoneMeshPoints.size(),
1790 forAll(curGlobalZonePointDispl, globalPointI)
1792 label localPoint = curMap[globalPointI];
1794 curZonePointDispl[localPoint] =
1795 curGlobalZonePointDispl[globalPointI];
1798 forAll(curZonePointDispl, pointI)
1801 if (curZoneMeshPoints[pointI] >= structuresMesh.nPoints())
1803 newPoints[curZoneMeshPoints[pointI]] +=
1804 curZonePointDispl[pointI];
1809 twoDPointCorrector twoDCorrector(structuresMesh);
1810 twoDCorrector.correctPoints(newPoints);
1811 structuresMesh.movePoints(newPoints);
1812 structuresMesh.V00();
1813 structuresMesh.moving(
false);
1817 FatalErrorIn(args.executable())
1818 <<
"FsiFoam:Step: Negative Jacobian"
1819 << exit(FatalError);
1822 if (runTime.outputTime())
1824 volScalarField sigmaEq
1832 IOobject::AUTO_WRITE
1834 sqrt((3.0/2.0)*magSqr(dev(sigma)))
1837 Info<<
"FsiFoam:Step: Max sigmaEq = " << max(sigmaEq).value()
1854 Foam::argList &args(this->ArgList());
1855 Foam::Time &runTime(this->RunTime());
1856 dynamicFvMesh &fluidsMesh(this->FluidMesh());
1858 dimensionedScalar &nu(this->nu());
1859 dimensionedScalar &rhoFluid(this->rhoFluid());
1860 volScalarField &p(this->p());
1861 volVectorField &U(this->U());
1862 surfaceScalarField &phi(this->phi());
1867 label fluidPatchID(this->FluidPatchID());
1868 label fluidZoneID(this->FluidZoneID());
1869 label solidZoneID(this->SolidZoneID());
1871 bool feMotionSolver(this->FEMotion());
1872 bool fvMotionSolver(this->FVMotion());
1873 vectorField &accumulatedFluidInterfaceDisplacement(this->AccumulatedFluidInterfaceDisplacements());
1875 Info <<
"FsiFoam:StepFluidAlone: Checking AccumulatedFluidInterfaceDisplacementi = " << endl;
1876 Info << accumulatedFluidInterfaceDisplacement;
1878 solidTractionFvPatchVectorField &tForce(this->tForce());
1880 zoneToZoneInterpolation &interpolatorFluidSolid(this->interpFluidSolid());
1881 zoneToZoneInterpolation &interpolatorSolidFluid(this->interpSolidFluid());
1883 scalar &sumLocalContErr(this->LocalContErr());
1884 scalar &globalContErr(this->GlobalContErr());
1885 scalar &cumulativeContErr(this->CumulativeContErr());
1887 labelList &globalFaceZones(this->GlobalFaceZones());
1888 labelListList &globalToLocalFaceZonePointMap(this->GlobalToLocalFaceZonePointMap());
1892 this->ReadPISOControls();
1893 this->ReadFSIControls();
1894 word couplingScheme(this->CouplingScheme());
1896 scalar &fsiRelaxationFactor(this->FSIRelaxationFactor());
1898 Switch fsi(this->FSIEnabled());
1899 int &nCorrPISO(this->NCorrPISO());
1900 int &nNonOrthCorr(this->NNonOrthCorr());
1901 scalar &interfaceDeformationLimit(this->InterfaceDeformationLimit());
1902 scalar &outerCorrTolerance(this->OuterCorrTolerance());
1903 int &nOuterCorr(this->NOuterCorr());
1905 vectorField fluidPatchPointsDispl
1907 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
1911 vectorField fluidPatchPointsDisplOld
1913 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
1917 vectorField solidPatchPointsDispl
1919 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
1923 vectorField fsiResidual
1925 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
1929 vectorField fsiResidualOld
1931 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
1936 scalar initialFsiResidualNorm = 0;
1937 scalar fsiResidualNorm = 0;
1943 Info <<
"FsiFoam:StepFluidAlone: outerCorr = " << outerCorr << endl;
1946 Info <<
"\nFsiFoam:StepFluidAlone: Time = " << runTime.timeName()
1947 <<
", iteration: " << outerCorr << endl;
1949 if (outerCorr < 3 || couplingScheme ==
"FixedRelaxation")
1951 Info <<
"FsiFoam:StepFluidAlone: Current fsi under-relaxation factor: "
1952 << fsiRelaxationFactor << endl;
1954 fluidPatchPointsDisplOld = fluidPatchPointsDispl;
1956 fluidPatchPointsDispl += fsiRelaxationFactor*fsiResidual;
1960 if (couplingScheme ==
"Aitken")
1962 fsiRelaxationFactor =
1963 -fsiRelaxationFactor
1968 &(fsiResidual - fsiResidualOld)
1973 (fsiResidual - fsiResidualOld)
1974 &(fsiResidual - fsiResidualOld)
1979 fsiRelaxationFactor = mag(fsiRelaxationFactor);
1981 Info <<
"FsiFoam:StepFluidAlone: Current fsi under-relaxation factor (Aitken): "
1982 << fsiRelaxationFactor << endl;
1984 fluidPatchPointsDisplOld = fluidPatchPointsDispl;
1986 fluidPatchPointsDispl +=
1987 fsiRelaxationFactor*fsiResidual;
1993 const vectorField& n =
1994 fluidsMesh.boundaryMesh()[fluidPatchID].pointNormals();
1996 primitivePatchInterpolation patchInterpolator
1998 fluidsMesh.boundaryMesh()[fluidPatchID]
2001 scalarField pointDeltaCoeffs =
2002 patchInterpolator.faceToPointInterpolate
2004 fluidsMesh.boundary()[fluidPatchID].deltaCoeffs()
2014 accumulatedFluidInterfaceDisplacement
2015 + fluidPatchPointsDispl
2016 - fluidPatchPointsDisplOld
2022 Info <<
"FsiFoam:StepFluidAlone: Maximal accumulated displacement of interface points: "
2025 if(delta < interfaceDeformationLimit)
2029 Info <<
"FsiFoam:StepFluidAlone: Moving only interface...";
2031 pointField newPoints = fluidsMesh.allPoints();
2033 const labelList& meshPoints =
2034 fluidsMesh.boundaryMesh()[fluidPatchID].meshPoints();
2036 forAll (fluidPatchPointsDispl, pointI)
2041 newPoints[meshPoints[pointI]] +=
2042 fluidPatchPointsDispl[pointI]
2043 - fluidPatchPointsDisplOld[pointI];
2046 twoDPointCorrector twoDCorrector(fluidsMesh);
2048 twoDCorrector.correctPoints(newPoints);
2050 fluidsMesh.movePoints(newPoints);
2053 accumulatedFluidInterfaceDisplacement +=
2054 fluidPatchPointsDispl
2055 - fluidPatchPointsDisplOld;
2061 Info <<
"FsiFoam:StepFluidAlone: Moving the whole mesh...";
2063 pointField newPoints = fluidsMesh.allPoints();
2065 const labelList& meshPoints =
2066 fluidsMesh.boundaryMesh()[fluidPatchID].meshPoints();
2068 forAll (accumulatedFluidInterfaceDisplacement, pointI)
2072 newPoints[meshPoints[pointI]] -=
2073 accumulatedFluidInterfaceDisplacement[pointI];
2076 twoDPointCorrector twoDCorrector(fluidsMesh);
2078 twoDCorrector.correctPoints(newPoints);
2080 fluidsMesh.movePoints(newPoints);
2082 accumulatedFluidInterfaceDisplacement +=
2083 fluidPatchPointsDispl
2084 - fluidPatchPointsDisplOld;
2089 tetPointVectorField& motionU =
2090 const_cast<tetPointVectorField&
>
2092 fluidsMesh.objectRegistry::
lookupObject<tetPointVectorField>
2098 fixedValueTetPolyPatchVectorField& motionUFluidPatch =
2099 refCast<fixedValueTetPolyPatchVectorField>
2101 motionU.boundaryField()[fluidPatchID]
2104 tetPolyPatchInterpolation tppi
2106 refCast<const faceTetPolyPatch>(motionUFluidPatch.patch())
2109 motionUFluidPatch ==
2110 tppi.pointToPointInterpolate
2112 accumulatedFluidInterfaceDisplacement
2113 /runTime.deltaT().value()
2116 else if (fvMotionSolver)
2118 pointVectorField& motionU =
2119 const_cast<pointVectorField&
>
2121 fluidsMesh.objectRegistry::
lookupObject<pointVectorField>
2127 fixedValuePointPatchVectorField& motionUFluidPatch =
2128 refCast<fixedValuePointPatchVectorField>
2130 motionU.boundaryField()[fluidPatchID]
2133 motionUFluidPatch ==
2134 accumulatedFluidInterfaceDisplacement
2135 /runTime.deltaT().value();
2139 FatalErrorIn(args.executable())
2140 <<
"FsiFoam:StepFluidAlone: Problem with mesh motion solver selection"
2141 << abort(FatalError);
2144 fluidsMesh.update();
2146 accumulatedFluidInterfaceDisplacement = vector::zero;
2150 if(fluidsMesh.moving())
2153 phi -= fvc::meshPhi(U);
2158 scalar meanCoNum = 0.0;
2159 scalar velMag = 0.0;
2161 if (fluidsMesh.nInternalFaces())
2163 surfaceScalarField magPhi = mag(phi);
2165 surfaceScalarField SfUfbyDelta =
2166 fluidsMesh.surfaceInterpolation::deltaCoeffs()*magPhi;
2168 const scalar deltaT = runTime.deltaT().value();
2170 CoNum = max(SfUfbyDelta/fluidsMesh.magSf()).value()*deltaT;
2172 meanCoNum = (sum(SfUfbyDelta)/sum(fluidsMesh.magSf())).value()*deltaT;
2174 velMag = max(magPhi/fluidsMesh.magSf()).value();
2177 Info<<
"FsiFoam:StepFluidAlone: Courant Number mean: " << meanCoNum
2178 <<
" max: " << CoNum
2179 <<
" velocity magnitude: " << velMag
2186 - fvm::laplacian(nu, U)
2189 solve(UEqn == -fvc::grad(p));
2192 volScalarField rUA = 1.0/UEqn.A();
2194 Info <<
"FsiFoam:StepFluidAlone: Performing " << nCorrPISO <<
" Pressure corrections." << endl;
2197 for (
int corr=0; corr<nCorrPISO; corr++)
2200 phi = (fvc::interpolate(U) & fluidsMesh.Sf());
2202 adjustPhi(phi, U, p);
2204 for (
int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
2208 fvm::laplacian(rUA, p)
2212 pEqn.setReference(pRefCell, pRefValue);
2218 if (nonOrth == nNonOrthCorr)
2225 volScalarField contErr = fvc::div(phi);
2227 sumLocalContErr = runTime.deltaT().value()*
2228 mag(contErr)().weightedAverage(fluidsMesh.V()).value();
2230 globalContErr = runTime.deltaT().value()*
2231 contErr.weightedAverage(fluidsMesh.V()).value();
2233 cumulativeContErr += globalContErr;
2235 Info<<
"FsiFoam:StepFluidAlone: time step continuity errors : sum local = " << sumLocalContErr
2236 <<
", global = " << globalContErr
2237 <<
", cumulative = " << cumulativeContErr
2241 U -= rUA*fvc::grad(p);
2242 U.correctBoundaryConditions();
2246 Info <<
"FsiFoam:StepFluidAlone: Not Setting traction on solid patch" << endl;
2250 fsiResidualOld = fsiResidual;
2260 this->UpdateFSISurface(solidPatchPointsDispl);
2262 solidPatchPointsDispl = vector::zero;
2268 Info <<
"FsiFoam:StepFluidAlone: solidPatchPointsDispl = " << solidPatchPointsDispl << endl;
2273 fsiResidual = (solidPatchPointsDispl - fluidPatchPointsDispl);
2277 fsiResidualNorm = ::sqrt(gSum(magSqr(fsiResidual)));
2281 initialFsiResidualNorm = fsiResidualNorm;
2284 fsiResidualNorm /= initialFsiResidualNorm + SMALL;
2286 Info <<
"FsiFoam:StepFluidAlone: Current fsi residual norm: " << fsiResidualNorm << endl;
2292 (fsiResidualNorm > outerCorrTolerance)
2293 && (outerCorr < nOuterCorr)
2297 if (runTime.outputTime())
2308 Foam::argList &args(this->ArgList());
2309 Foam::Time &runTime(this->RunTime());
2310 dynamicFvMesh &fluidsMesh(this->FluidMesh());
2312 dimensionedScalar &nu(this->nu());
2313 dimensionedScalar &rhoFluid(this->rhoFluid());
2314 volScalarField &p(this->p());
2315 volVectorField &U(this->U());
2316 surfaceScalarField &phi(this->phi());
2321 label fluidPatchID(this->FluidPatchID());
2322 label fluidZoneID(this->FluidZoneID());
2323 label solidZoneID(this->SolidZoneID());
2325 bool feMotionSolver(this->FEMotion());
2326 bool fvMotionSolver(this->FVMotion());
2327 vectorField &accumulatedFluidInterfaceDisplacement(this->AccumulatedFluidInterfaceDisplacements());
2330 solidTractionFvPatchVectorField &tForce(this->tForce());
2332 zoneToZoneInterpolation &interpolatorFluidSolid(this->interpFluidSolid());
2333 zoneToZoneInterpolation &interpolatorSolidFluid(this->interpSolidFluid());
2335 scalar &sumLocalContErr(this->LocalContErr());
2336 scalar &globalContErr(this->GlobalContErr());
2337 scalar &cumulativeContErr(this->CumulativeContErr());
2339 labelList &globalFaceZones(this->GlobalFaceZones());
2340 labelListList &globalToLocalFaceZonePointMap(this->GlobalToLocalFaceZonePointMap());
2344 this->ReadPISOControls();
2345 this->ReadFSIControls();
2346 word couplingScheme(this->CouplingScheme());
2348 scalar &fsiRelaxationFactor(this->FSIRelaxationFactor());
2350 Switch fsi(this->FSIEnabled());
2351 int &nCorrPISO(this->NCorrPISO());
2352 int &nNonOrthCorr(this->NNonOrthCorr());
2353 scalar &interfaceDeformationLimit(this->InterfaceDeformationLimit());
2354 scalar &outerCorrTolerance(this->OuterCorrTolerance());
2355 int &nOuterCorr(this->NOuterCorr());
2357 vectorField fluidPatchPointsDispl
2359 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
2363 vectorField fluidPatchPointsDisplOld
2365 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
2369 vectorField solidPatchPointsDispl
2371 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
2375 vectorField fsiResidual
2377 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
2381 vectorField fsiResidualOld
2383 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
2388 scalar initialFsiResidualNorm = 0;
2389 scalar fsiResidualNorm = 0;
2395 Info <<
"FsiFoam:StepFluidNonItr: outerCorr = " << outerCorr << endl;
2398 Info <<
"FsiFoam:StepFluidNonItr: Time = " << runTime.timeName()
2399 <<
", iteration: " << outerCorr << endl;
2401 this->UpdateFSISurface(fluidPatchPointsDispl);
2406 const vectorField& n =
2407 fluidsMesh.boundaryMesh()[fluidPatchID].pointNormals();
2409 primitivePatchInterpolation patchInterpolator
2411 fluidsMesh.boundaryMesh()[fluidPatchID]
2414 scalarField pointDeltaCoeffs =
2415 patchInterpolator.faceToPointInterpolate
2417 fluidsMesh.boundary()[fluidPatchID].deltaCoeffs()
2427 accumulatedFluidInterfaceDisplacement
2428 + fluidPatchPointsDispl
2434 Info <<
"FsiFoam:StepFluidNonItr: Maximal accumulated displacement of interface points: "
2437 if(delta < interfaceDeformationLimit)
2440 Info <<
"FsiFoam:StepFluidNonItr: Moving only interface...";
2441 pointField newPoints = fluidsMesh.allPoints();
2443 const labelList& meshPoints =
2444 fluidsMesh.boundaryMesh()[fluidPatchID].meshPoints();
2446 forAll (fluidPatchPointsDispl, pointI)
2451 newPoints[meshPoints[pointI]] +=
2452 fluidPatchPointsDispl[pointI];
2455 twoDPointCorrector twoDCorrector(fluidsMesh);
2457 twoDCorrector.correctPoints(newPoints);
2459 fluidsMesh.movePoints(newPoints);
2462 accumulatedFluidInterfaceDisplacement +=
2463 fluidPatchPointsDispl;
2468 Info <<
"FsiFoam:StepFluidNonItr: Moving the whole mesh...";
2469 pointField newPoints = fluidsMesh.allPoints();
2471 const labelList& meshPoints =
2472 fluidsMesh.boundaryMesh()[fluidPatchID].meshPoints();
2474 forAll (accumulatedFluidInterfaceDisplacement, pointI)
2478 newPoints[meshPoints[pointI]] -=
2479 accumulatedFluidInterfaceDisplacement[pointI];
2482 twoDPointCorrector twoDCorrector(fluidsMesh);
2484 twoDCorrector.correctPoints(newPoints);
2486 fluidsMesh.movePoints(newPoints);
2488 accumulatedFluidInterfaceDisplacement +=
2489 fluidPatchPointsDispl;
2493 tetPointVectorField& motionU =
2494 const_cast<tetPointVectorField&
>
2496 fluidsMesh.objectRegistry::
lookupObject<tetPointVectorField>
2502 fixedValueTetPolyPatchVectorField& motionUFluidPatch =
2503 refCast<fixedValueTetPolyPatchVectorField>
2505 motionU.boundaryField()[fluidPatchID]
2508 tetPolyPatchInterpolation tppi
2510 refCast<const faceTetPolyPatch>(motionUFluidPatch.patch())
2513 motionUFluidPatch ==
2514 tppi.pointToPointInterpolate
2516 accumulatedFluidInterfaceDisplacement
2517 /runTime.deltaT().value()
2520 else if (fvMotionSolver)
2522 pointVectorField& motionU =
2523 const_cast<pointVectorField&
>
2525 fluidsMesh.objectRegistry::
lookupObject<pointVectorField>
2531 fixedValuePointPatchVectorField& motionUFluidPatch =
2532 refCast<fixedValuePointPatchVectorField>
2534 motionU.boundaryField()[fluidPatchID]
2537 motionUFluidPatch ==
2538 accumulatedFluidInterfaceDisplacement
2539 /runTime.deltaT().value();
2543 FatalErrorIn(args.executable())
2544 <<
"FsiFoam:StepFluidNonItr: Problem with mesh motion solver selection"
2545 << abort(FatalError);
2549 Info <<
"FsiFoam:StepFluidNonItr: runTime.deltaT() = "
2550 << runTime.deltaT().value() << endl;
2553 fluidsMesh.update();
2555 accumulatedFluidInterfaceDisplacement = vector::zero;
2559 if(fluidsMesh.moving())
2562 Info <<
"FsiFoam:StepFluidNonItr: Compensating for mesh movment !" << endl;
2563 phi -= fvc::meshPhi(U);
2568 scalar meanCoNum = 0.0;
2569 scalar velMag = 0.0;
2571 if (fluidsMesh.nInternalFaces())
2573 surfaceScalarField magPhi = mag(phi);
2575 surfaceScalarField SfUfbyDelta =
2576 fluidsMesh.surfaceInterpolation::deltaCoeffs()*magPhi;
2578 const scalar deltaT = runTime.deltaT().value();
2580 CoNum = max(SfUfbyDelta/fluidsMesh.magSf()).value()*deltaT;
2582 meanCoNum = (sum(SfUfbyDelta)/sum(fluidsMesh.magSf())).value()*deltaT;
2584 velMag = max(magPhi/fluidsMesh.magSf()).value();
2587 Info<<
"FsiFoam:StepFluidNonItr: Courant Number mean: " << meanCoNum
2588 <<
" max: " << CoNum
2589 <<
" velocity magnitude: " << velMag
2596 - fvm::laplacian(nu, U)
2599 solve(UEqn == -fvc::grad(p));
2602 volScalarField rUA = 1.0/UEqn.A();
2605 for (
int corr=0; corr<nCorrPISO; corr++)
2608 phi = (fvc::interpolate(U) & fluidsMesh.Sf());
2610 adjustPhi(phi, U, p);
2612 for (
int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
2616 fvm::laplacian(rUA, p)
2620 pEqn.setReference(pRefCell, pRefValue);
2625 if (nonOrth == nNonOrthCorr)
2632 volScalarField contErr = fvc::div(phi);
2634 sumLocalContErr = runTime.deltaT().value()*
2635 mag(contErr)().weightedAverage(fluidsMesh.V()).value();
2637 globalContErr = runTime.deltaT().value()*
2638 contErr.weightedAverage(fluidsMesh.V()).value();
2640 cumulativeContErr += globalContErr;
2642 Info<<
"FsiFoam:StepFluidNonItr: time step continuity errors : sum local = " << sumLocalContErr
2643 <<
", global = " << globalContErr
2644 <<
", cumulative = " << cumulativeContErr
2648 U -= rUA*fvc::grad(p);
2649 U.correctBoundaryConditions();
2657 if (runTime.outputTime())
2670 Foam::argList &args(this->ArgList());
2671 Foam::Time &runTime(this->RunTime());
2672 dynamicFvMesh &fluidsMesh(this->FluidMesh());
2674 dimensionedScalar &nu(this->nu());
2675 dimensionedScalar &rhoFluid(this->rhoFluid());
2676 volScalarField &p(this->p());
2677 volVectorField &U(this->U());
2678 surfaceScalarField &phi(this->phi());
2683 label fluidPatchID(this->FluidPatchID());
2684 label fluidZoneID(this->FluidZoneID());
2685 label solidZoneID(this->SolidZoneID());
2687 bool feMotionSolver(this->FEMotion());
2688 bool fvMotionSolver(this->FVMotion());
2689 vectorField &accumulatedFluidInterfaceDisplacement(this->AccumulatedFluidInterfaceDisplacements());
2691 Info <<
"FsiFoam:StepFluidItr: Checking AccumulatedFluidInterfaceDisplacementi = " << endl;
2692 Info << accumulatedFluidInterfaceDisplacement;
2694 solidTractionFvPatchVectorField &tForce(this->tForce());
2696 zoneToZoneInterpolation &interpolatorFluidSolid(this->interpFluidSolid());
2697 zoneToZoneInterpolation &interpolatorSolidFluid(this->interpSolidFluid());
2699 scalar &sumLocalContErr(this->LocalContErr());
2700 scalar &globalContErr(this->GlobalContErr());
2701 scalar &cumulativeContErr(this->CumulativeContErr());
2703 labelList &globalFaceZones(this->GlobalFaceZones());
2704 labelListList &globalToLocalFaceZonePointMap(this->GlobalToLocalFaceZonePointMap());
2708 this->ReadPISOControls();
2709 this->ReadFSIControls();
2710 word couplingScheme(this->CouplingScheme());
2712 scalar &fsiRelaxationFactor(this->FSIRelaxationFactor());
2714 Switch fsi(this->FSIEnabled());
2715 int &nCorrPISO(this->NCorrPISO());
2716 int &nNonOrthCorr(this->NNonOrthCorr());
2717 scalar &interfaceDeformationLimit(this->InterfaceDeformationLimit());
2718 scalar &outerCorrTolerance(this->OuterCorrTolerance());
2719 int &nOuterCorr(this->NOuterCorr());
2721 vectorField fluidPatchPointsDispl
2723 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
2727 vectorField fluidPatchPointsDisplOld
2729 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
2733 vectorField solidPatchPointsDispl
2735 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
2739 vectorField fsiResidual
2741 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
2745 vectorField fsiResidualOld
2747 fluidsMesh.boundaryMesh()[fluidPatchID].nPoints(),
2752 scalar initialFsiResidualNorm = 0;
2753 scalar fsiResidualNorm = 0;
2759 Info <<
"FsiFoam:StepFluidItr: outerCorr = " << outerCorr << endl;
2762 Info <<
"\nFsiFoam:StepFluidItr: Time = " << runTime.timeName()
2763 <<
", iteration: " << outerCorr << endl;
2765 if (outerCorr < 3 || couplingScheme ==
"FixedRelaxation")
2767 Info <<
"FsiFoam:StepFluidItr: Current fsi under-relaxation factor: "
2768 << fsiRelaxationFactor << endl;
2770 fluidPatchPointsDisplOld = fluidPatchPointsDispl;
2772 fluidPatchPointsDispl += fsiRelaxationFactor*fsiResidual;
2776 if (couplingScheme ==
"Aitken")
2778 fsiRelaxationFactor =
2779 -fsiRelaxationFactor
2784 &(fsiResidual - fsiResidualOld)
2789 (fsiResidual - fsiResidualOld)
2790 &(fsiResidual - fsiResidualOld)
2795 fsiRelaxationFactor = mag(fsiRelaxationFactor);
2797 Info <<
"FsiFoam:StepFluidItr: Current fsi under-relaxation factor (Aitken): "
2798 << fsiRelaxationFactor << endl;
2800 fluidPatchPointsDisplOld = fluidPatchPointsDispl;
2802 fluidPatchPointsDispl +=
2803 fsiRelaxationFactor*fsiResidual;
2809 const vectorField& n =
2810 fluidsMesh.boundaryMesh()[fluidPatchID].pointNormals();
2812 primitivePatchInterpolation patchInterpolator
2814 fluidsMesh.boundaryMesh()[fluidPatchID]
2817 scalarField pointDeltaCoeffs =
2818 patchInterpolator.faceToPointInterpolate
2820 fluidsMesh.boundary()[fluidPatchID].deltaCoeffs()
2830 accumulatedFluidInterfaceDisplacement
2831 + fluidPatchPointsDispl
2832 - fluidPatchPointsDisplOld
2838 Info <<
"FsiFoam:StepFluidItr: Maximal accumulated displacement of interface points: "
2841 if(delta < interfaceDeformationLimit)
2845 Info <<
"FsiFoam:StepFluidItr: Moving only interface...";
2847 pointField newPoints = fluidsMesh.allPoints();
2849 const labelList& meshPoints =
2850 fluidsMesh.boundaryMesh()[fluidPatchID].meshPoints();
2852 forAll (fluidPatchPointsDispl, pointI)
2857 newPoints[meshPoints[pointI]] +=
2858 fluidPatchPointsDispl[pointI]
2859 - fluidPatchPointsDisplOld[pointI];
2862 twoDPointCorrector twoDCorrector(fluidsMesh);
2864 twoDCorrector.correctPoints(newPoints);
2866 fluidsMesh.movePoints(newPoints);
2869 accumulatedFluidInterfaceDisplacement +=
2870 fluidPatchPointsDispl
2871 - fluidPatchPointsDisplOld;
2877 Info <<
"FsiFoam:StepFluidItr: Moving the whole mesh...";
2879 pointField newPoints = fluidsMesh.allPoints();
2881 const labelList& meshPoints =
2882 fluidsMesh.boundaryMesh()[fluidPatchID].meshPoints();
2884 forAll (accumulatedFluidInterfaceDisplacement, pointI)
2888 newPoints[meshPoints[pointI]] -=
2889 accumulatedFluidInterfaceDisplacement[pointI];
2892 twoDPointCorrector twoDCorrector(fluidsMesh);
2894 twoDCorrector.correctPoints(newPoints);
2896 fluidsMesh.movePoints(newPoints);
2898 accumulatedFluidInterfaceDisplacement +=
2899 fluidPatchPointsDispl
2900 - fluidPatchPointsDisplOld;
2905 tetPointVectorField& motionU =
2906 const_cast<tetPointVectorField&
>
2908 fluidsMesh.objectRegistry::
lookupObject<tetPointVectorField>
2914 fixedValueTetPolyPatchVectorField& motionUFluidPatch =
2915 refCast<fixedValueTetPolyPatchVectorField>
2917 motionU.boundaryField()[fluidPatchID]
2920 tetPolyPatchInterpolation tppi
2922 refCast<const faceTetPolyPatch>(motionUFluidPatch.patch())
2925 motionUFluidPatch ==
2926 tppi.pointToPointInterpolate
2928 accumulatedFluidInterfaceDisplacement
2929 /runTime.deltaT().value()
2932 else if (fvMotionSolver)
2934 pointVectorField& motionU =
2935 const_cast<pointVectorField&
>
2937 fluidsMesh.objectRegistry::
lookupObject<pointVectorField>
2943 fixedValuePointPatchVectorField& motionUFluidPatch =
2944 refCast<fixedValuePointPatchVectorField>
2946 motionU.boundaryField()[fluidPatchID]
2949 motionUFluidPatch ==
2950 accumulatedFluidInterfaceDisplacement
2951 /runTime.deltaT().value();
2955 FatalErrorIn(args.executable())
2956 <<
"FsiFoam:StepFluidItr: Problem with mesh motion solver selection"
2957 << abort(FatalError);
2960 fluidsMesh.update();
2962 accumulatedFluidInterfaceDisplacement = vector::zero;
2966 if(fluidsMesh.moving())
2969 phi -= fvc::meshPhi(U);
2974 scalar meanCoNum = 0.0;
2975 scalar velMag = 0.0;
2977 if (fluidsMesh.nInternalFaces())
2979 surfaceScalarField magPhi = mag(phi);
2981 surfaceScalarField SfUfbyDelta =
2982 fluidsMesh.surfaceInterpolation::deltaCoeffs()*magPhi;
2984 const scalar deltaT = runTime.deltaT().value();
2986 CoNum = max(SfUfbyDelta/fluidsMesh.magSf()).value()*deltaT;
2988 meanCoNum = (sum(SfUfbyDelta)/sum(fluidsMesh.magSf())).value()*deltaT;
2990 velMag = max(magPhi/fluidsMesh.magSf()).value();
2993 Info<<
"FsiFoam:StepFluidItr: Courant Number mean: " << meanCoNum
2994 <<
" max: " << CoNum
2995 <<
" velocity magnitude: " << velMag
3002 - fvm::laplacian(nu, U)
3005 solve(UEqn == -fvc::grad(p));
3008 volScalarField rUA = 1.0/UEqn.A();
3010 Info <<
"FsiFoam:StepFluidItr: Performing " << nCorrPISO <<
" Pressure corrections." << endl;
3013 for (
int corr=0; corr<nCorrPISO; corr++)
3016 phi = (fvc::interpolate(U) & fluidsMesh.Sf());
3018 adjustPhi(phi, U, p);
3020 for (
int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
3024 fvm::laplacian(rUA, p)
3028 pEqn.setReference(pRefCell, pRefValue);
3034 if (nonOrth == nNonOrthCorr)
3041 volScalarField contErr = fvc::div(phi);
3043 sumLocalContErr = runTime.deltaT().value()*
3044 mag(contErr)().weightedAverage(fluidsMesh.V()).value();
3046 globalContErr = runTime.deltaT().value()*
3047 contErr.weightedAverage(fluidsMesh.V()).value();
3049 cumulativeContErr += globalContErr;
3051 Info<<
"FsiFoam:StepFluidItr: time step continuity errors : sum local = " << sumLocalContErr
3052 <<
", global = " << globalContErr
3053 <<
", cumulative = " << cumulativeContErr
3057 U -= rUA*fvc::grad(p);
3058 U.correctBoundaryConditions();
3062 Info <<
"FsiFoam:StepFluidItr: Setting tractionis on solid patch" << endl;
3066 fsiResidualOld = fsiResidual;
3067 this->UpdateFSISurface(solidPatchPointsDispl);
3068 Info <<
"FsiFoam:StepFluidItr: solidPatchPointsDispl = " << solidPatchPointsDispl << endl;
3070 fsiResidual = (solidPatchPointsDispl - fluidPatchPointsDispl);
3071 fsiResidualNorm = ::sqrt(gSum(magSqr(fsiResidual)));
3075 initialFsiResidualNorm = fsiResidualNorm;
3078 fsiResidualNorm /= initialFsiResidualNorm + SMALL;
3080 Info <<
"FsiFoam:StepFluidItr: Current fsi residual norm: " << fsiResidualNorm << endl;
3086 (fsiResidualNorm > outerCorrTolerance)
3087 && (outerCorr < nOuterCorr)
3091 if (runTime.outputTime())
3101 Foam::Time &runTime(this->RunTime());
3102 fvMesh &structuresMesh(this->StructuresMesh());
3103 volSymmTensorField &sigma(this->sigma());
3104 volScalarField sigmaEq
3112 IOobject::AUTO_WRITE
3114 sqrt((3.0/2.0)*magSqr(dev(sigma)))
3117 Info<<
"FsiFoam:Dump: Max sigmaEq = " << max(sigmaEq).value()
3130 std::cout <<
"FsiFoam:Load: Loading FsiFoamModule with name " << name
3131 <<
"." << std::endl;
3135 COM_new_window(name, MPI_COMM_NULL);
3137 std::string global_name(name+
".global");
3138 COM_new_dataitem(global_name.c_str(),
'w',COM_VOID,1,
"");
3139 COM_set_object(global_name.c_str(),0,module_pointer);
3143 std::vector<COM_Type> types(13,COM_INT);
3145 types[0] = COM_RAWDATA;
3146 types[2] = COM_VOID;
3147 COM_set_member_function( (name+
".InitFoam").c_str(),
3149 global_name.c_str(),
"biii", &types[0]);
3151 COM_set_member_function( (name+
".RunFoam").c_str(),
3153 global_name.c_str(),
"b", &types[0]);
3156 COM_set_member_function( (name+
".StepFoam").c_str(),
3158 global_name.c_str(),
"b", &types[0]);
3160 COM_set_member_function( (name+
".StepFluid").c_str(),
3162 global_name.c_str(),
"b", &types[0]);
3172 COM_window_init_done(name);
3179 char** argv = (
char**)(pargv);
3180 verbosity = *verbIn;
3182 std::cout <<
"OF Module verbosity = " << verbosity << std::endl;
3191 Initialize(argc, argv);
3196 Solution().Meta().AddField(
"time",
's', 1, 8,
"s");
3197 Solution().Meta().AddField(
"endTime",
's', 1, 8,
"s");
3198 Solution().Meta().AddField(
"initStatus",
's', 1, 4,
"");
3199 Solution().Meta().AddField(
"runStatus",
's', 1, 4,
"");
3200 Solution().Meta().AddField(
"dt",
's', 1, 8,
"s");
3201 Solution().Meta().AddField(
"solidDisplacement",
'n', 3, 8,
"m");
3202 Solution().Meta().AddField(
"pressure",
'c', 1, 8,
"Pa");
3203 Solution().Meta().AddField(
"traction",
'c', 3, 8,
"N");
3205 Mesh().nc.init(numPointsSurface, &surfaceCoordinates[0]);
3207 Mesh().con.AddElements(numElementsSurface, 4, surfaceConnectivity);
3217 time.resize(1, -1.0);
3218 endTime.resize(1, -1.0);
3221 initStatus.resize(1, -1000);
3222 runStatus.resize(1, -1000);
3224 surfacePressure.resize(numElementsSurface, -1);
3225 surfaceTraction.resize(3*numElementsSurface, -1);
3226 solidDisplacement.resize(3*numPointsSurface,0.);
3229 Solution().SetFieldBuffer(
"initStatus", initStatus);
3230 Solution().SetFieldBuffer(
"runStatus", runStatus);
3231 Solution().SetFieldBuffer(
"time", time);
3232 Solution().SetFieldBuffer(
"endTime", endTime);
3233 Solution().SetFieldBuffer(
"pressure", surfacePressure);
3234 Solution().SetFieldBuffer(
"traction", surfaceTraction);
3235 Solution().SetFieldBuffer(
"solidDisplacement", solidDisplacement);
3237 SolverUtils::RegisterSolverInto(my_window_name.c_str(), *
this);
3250 std::cout <<
"FsiFoam:Unload: Unloading FsiFoamModule with name " << name
3251 <<
"." << std::endl;
3253 std::string global_name(name+
".global");
3254 COM_get_object(global_name.c_str(),0,&module_pointer);
3255 COM_assertion_msg( module_pointer->validate_object()==0,
"Invalid object");
3256 delete module_pointer;
3257 COM_delete_window(std::string(name));
3266 Foam::Time &runTime(RunTime());
3268 Info <<
"\nFsiFoam:RunFoam: Starting time loop\n" << endl;
3270 while(!runTime.end()){
3271 Info <<
"FsiFoam:RunFoam: Time = " << runTime.timeName() << nl << endl;
3273 Info<<
"ExecutionTime = " << runTime.elapsedCpuTime() <<
" s"
3274 <<
" ClockTime = " << runTime.elapsedClockTime() <<
" s"
3276 if (runTime.outputTime())
3280 Info<<
"FsiFoam:RunFoam: End\n" << endl;
3292 Foam::Time &runTime(RunTime());
3294 Info <<
"\nFsiFoam:StepFoam: Stepping time loop\n" << endl;
3298 Info <<
"FsiFoam:StepFoam: Time = " << runTime.timeName() << nl << endl;
3300 Info<<
"ExecutionTime = " << runTime.elapsedCpuTime() <<
" s"
3301 <<
" ClockTime = " << runTime.elapsedClockTime() <<
" s"
3303 if (runTime.outputTime())
3308 UpdateFSISurfaceData();
3310 UpdateFSISurfaceMesh();
3314 Info <<
"FsiFoam:StepFoam: numPointSurface = " << numPointsSurface << endl;
3315 Info <<
"FsiFoam:StepFoam: numElementSurface = " << numElementsSurface << endl;
3316 Info <<
"FsiFoam:StepFoam: SurfaceCoordinates = " << endl;
3317 for (
int i = 0; i < numPointsSurface; i++)
3319 Info << surfaceCoordinates[i*3] <<
" "
3320 << surfaceCoordinates[i*3+1] <<
" "
3321 << surfaceCoordinates[i*3+2] << endl;
3327 Info<<
"End\n" << endl;
3339 ofstream prb2DmpFile;
3340 dynamicFvMesh &fluidsMesh(this->FluidMesh());
3341 pointField foamCoords = fluidsMesh.allPoints();
3344 Foam::Time &runTime(RunTime());
3346 Info <<
"FsiFoam:StepFluid: Stepping fluid solver..." << endl;
3350 Info <<
"FsiFoam:StepFluid: Time = " << runTime.timeName() << endl;
3363 Info<<
"FsiFoam:StepFluid: ExecutionTime = " << runTime.elapsedCpuTime() <<
" s"
3364 <<
" ClockTime = " << runTime.elapsedClockTime() <<
" s"
3366 if (runTime.outputTime())
3371 UpdateFSISurfaceData();
3372 UpdateFSISurfaceMesh();
3387 prb2DmpFile.open(
"prb2.dat", std::ios::app);
3388 prb2DmpFile << runTime.timeName() <<
" " << \
3389 foamCoords[64].x() <<
" " << \
3390 foamCoords[64].y() <<
" " << \
3391 foamCoords[64].z() <<
"\n";
3392 prb2DmpFile.close();
3397 Info<<
"FsiFoam:StepFluid: End\n" << endl;
3411 dynamicFvMesh &fluidsMesh(this->FluidMesh());
3412 numPointsSurface = fluidsMesh.boundaryMesh()[fluidPatchID].nPoints();
3416 const faceList& faces = fluidsMesh.faces();
3417 const labelList& owner = fluidsMesh.faceOwner();
3418 const polyBoundaryMesh& boundaryMesh = fluidsMesh.boundaryMesh();
3419 const label start = boundaryMesh[fluidPatchID].start();
3420 const label end = start + boundaryMesh[fluidPatchID].size();
3421 numElementsSurface = end - start;
3424 const pointField points = fluidsMesh.points();
3428 for (label faceI = start; faceI < end; ++faceI) {
3429 const labelList& vrtList = faces[faceI];
3430 forAll(vrtList, i) {
3431 const label& vertex = vrtList[i];
3434 if (!surfaceNodeMap[vertex]) {
3435 surfaceNodeMap[vertex] = nodeNumber;
3436 interfaceToFoamNodeMap[nodeNumber] = vertex;
3439 surfaceCoordinates.push_back(points[vertex].x());
3440 surfaceCoordinates.push_back(points[vertex].y());
3441 surfaceCoordinates.push_back(points[vertex].z());
3444 surfaceConnectivity.push_back(vertex);
3449 const labelList& meshPoints =
3450 fluidsMesh.boundaryMesh()[fluidPatchID].meshPoints();
3451 for (
int i=0; i<numPointsSurface; ++i) {
3452 foamGlobalToPatchNodeMap[meshPoints[i]] = i;
3457 for (
unsigned int i=0; i<surfaceConnectivity.size(); ++i) {
3458 surfaceConnectivity[i] = surfaceNodeMap[surfaceConnectivity[i]];
3464 dynamicFvMesh &fluidsMesh(this->FluidMesh());
3465 pointField foamCoords = fluidsMesh.allPoints();
3467 for (
int i=0; i<numPointsSurface; ++i) {
3468 int vertex = interfaceToFoamNodeMap[i+1];
3469 surfaceCoordinates[3*i] = foamCoords[vertex].x();
3470 surfaceCoordinates[3*i+1] = foamCoords[vertex].y();
3471 surfaceCoordinates[3*i+2] = foamCoords[vertex].z();
3476 Foam::Time &runTime(this->RunTime());
3477 time[0] = runTime.value();
3478 endTime[0] = runTime.endTime().value();
3484 "FsiFoam:UpdateFSISurface: Reporting solid displacements to the fluid solver" << std::endl;
3490 for(
int i=0; i<numPointsSurface; ++i) {
3491 solidDispl[foamGlobalToPatchNodeMap[interfaceToFoamNodeMap[i+1]]].x() =
3492 solidDisplacement[3*i];
3493 solidDispl[foamGlobalToPatchNodeMap[interfaceToFoamNodeMap[i+1]]].y() =
3494 solidDisplacement[3*i+1];
3495 solidDispl[foamGlobalToPatchNodeMap[interfaceToFoamNodeMap[i+1]]].z() =
3496 solidDisplacement[3*i+2];
3509 double currTime((this->RunTime()).value());
3510 Info <<
"FsiFoam:UpdateFSISurface: Reporting surface loads to the solid solver " << endl;
3515 dimensionedScalar &rhoFluid(this->rhoFluid());
3516 volScalarField &p(this->p());
3518 scalarField foamSurfacePressure = rhoFluid.value()*p.boundaryField()[fluidPatchID];
3520 for(
int i=0; i<numElementsSurface; ++i) {
3521 surfacePressure[i] = foamSurfacePressure[i];
3527 dimensionedScalar &nu(this->nu());
3528 volVectorField &U(this->U());
3541 dynamicFvMesh &fluidsMesh(this->FluidMesh());
3542 vectorField foamSurfaceTraction = -rhoFluid.value()*nu.value()
3543 *U.boundaryField()[fluidPatchID].snGrad()
3544 + rhoFluid.value()*p.boundaryField()[fluidPatchID]
3545 *fluidsMesh.boundary()[fluidPatchID].nf();
3549 if (currTime > -0.1) {
3550 for(
int i=0; i<numElementsSurface; ++i) {
3551 surfaceTraction[3*i] = foamSurfaceTraction[i].x();
3552 surfaceTraction[3*i+1] = foamSurfaceTraction[i].y();
3553 surfaceTraction[3*i+2] = foamSurfaceTraction[i].z();
3556 for(
int i=0; i<numElementsSurface; ++i) {
3557 surfaceTraction[3*i] = 0.0;
3558 surfaceTraction[3*i+1] = 0.0;
3559 surfaceTraction[3*i+2] = 0.0;
3577 void UpdateFSISurfaceData()
Update the data registered on the FSI surface.
void StepFoam()
the OpenFOAM stepping
void InitFoam(int *pargc, void **pargv, int *verbIn)
function to register through IMPACT
int UpdateFSISurface(Foam::vectorField &solidPatchPointsDispl)
Update the nodal coordinates of the IMAPCT and OpenFoam FSI surfaces from the IMPACT displacement dat...
void UpdateTime()
Update the time control data registered with OpenFOAM i.e.
static void Load(const std::string &name)
"Loads" IcoFoamModule
static void Unload(const std::string &name)
Unloads the IcoFoamModule.
void RunFoam()
the OpenFOAM main
void OpenFoamFSI_load_module(const char *name)
C/C++ bindings to load IcoFoamModule.
int Initialize(int argc, char *argv[])
std::string my_window_name
void StepFluid()
the OpenFOAM stepping fluid alone
void UpdateFSISurfaceMesh()
Update of the surface mesh data coordinates.
int CreateInterZoneInterpolators()
void OpenFoamFSI_unload_module(const char *name)
C/C++ bindings to unload IcoFoamModule.
void CreateFSISurfaceMesh()
Initialization of the surface mesh data structures from the OpenFOAM mesh data structures.
int InitTransportProperties()
int ReadCouplingProperties()
int CreateStructuresFields()
int FindGlobalFaceZones()