|
| 1 | +#include "Stress.H" |
| 2 | + |
| 3 | +using namespace Foam; |
| 4 | + |
| 5 | +preciceAdapter::FSI::Stress::Stress |
| 6 | +( |
| 7 | + const Foam::fvMesh& mesh, |
| 8 | + const fileName& timeName, |
| 9 | + const std::string solverType |
| 10 | + /* TODO: We should add any required field names here. |
| 11 | + / They would need to be vector fields. |
| 12 | + / See FSI/Temperature.C for details. |
| 13 | + */ |
| 14 | +) |
| 15 | +: |
| 16 | +Force(mesh,solverType), |
| 17 | +mesh_(mesh), |
| 18 | +solverType_(solverType) |
| 19 | +{ |
| 20 | + if (solverType_.compare("incompressible") != 0 && solverType_.compare("compressible") != 0) |
| 21 | + { |
| 22 | + FatalErrorInFunction |
| 23 | + << "Stresses calculation only supports " |
| 24 | + << "compressible or incompressible solver type." |
| 25 | + << exit(FatalError); |
| 26 | + } |
| 27 | + |
| 28 | + dataType_ = vector; |
| 29 | + |
| 30 | + Stress_ = new volVectorField |
| 31 | + ( |
| 32 | + IOobject |
| 33 | + ( |
| 34 | + "Stress", |
| 35 | + timeName, |
| 36 | + mesh, |
| 37 | + IOobject::NO_READ, |
| 38 | + IOobject::AUTO_WRITE |
| 39 | + ), |
| 40 | + mesh, |
| 41 | + dimensionedVector |
| 42 | + ( |
| 43 | + "pdim", |
| 44 | + dimensionSet(1,-1,-2,0,0,0,0), |
| 45 | + Foam::vector::zero |
| 46 | + ) |
| 47 | + ); |
| 48 | +} |
| 49 | + |
| 50 | +void preciceAdapter::FSI::Stress::write(double * buffer, bool meshConnectivity, const unsigned int dim) |
| 51 | +{ |
| 52 | + // Compute stress. See the Forces function object. |
| 53 | + |
| 54 | + // Stress tensor boundary field |
| 55 | + tmp<volSymmTensorField> tdevRhoReff = this->devRhoReff(); |
| 56 | + const volSymmTensorField::Boundary& devRhoReffb = |
| 57 | + tdevRhoReff().boundaryField(); |
| 58 | + |
| 59 | + // Density boundary field |
| 60 | + tmp<volScalarField> trho = this->rho(); |
| 61 | + const volScalarField::Boundary& rhob = |
| 62 | + trho().boundaryField(); |
| 63 | + |
| 64 | + // Pressure boundary field |
| 65 | + tmp<volScalarField> tp = mesh_.lookupObject<volScalarField>("p"); |
| 66 | + const volScalarField::Boundary& pb = |
| 67 | + tp().boundaryField(); |
| 68 | + |
| 69 | + int bufferIndex = 0; |
| 70 | + // For every boundary patch of the interface |
| 71 | + for (uint j = 0; j < patchIDs_.size(); j++) |
| 72 | + { |
| 73 | + |
| 74 | + int patchID = patchIDs_.at(j); |
| 75 | + |
| 76 | + // Compute normal vectors on each patch |
| 77 | + const vectorField nV = mesh_.boundary()[patchID].nf(); |
| 78 | + |
| 79 | + // Pressure constribution |
| 80 | + if (solverType_.compare("incompressible") == 0) |
| 81 | + { |
| 82 | + Stress_->boundaryFieldRef()[patchID] = |
| 83 | + nV * pb[patchID] * rhob[patchID]; |
| 84 | + } |
| 85 | + else if (solverType_.compare("compressible") == 0) |
| 86 | + { |
| 87 | + Stress_->boundaryFieldRef()[patchID] = |
| 88 | + nV * pb[patchID]; |
| 89 | + } |
| 90 | + else |
| 91 | + { |
| 92 | + FatalErrorInFunction |
| 93 | + << "Stress calculation does only support " |
| 94 | + << "compressible or incompressible solver type." |
| 95 | + << exit(FatalError); |
| 96 | + } |
| 97 | + |
| 98 | + // Viscous contribution |
| 99 | + Stress_->boundaryFieldRef()[patchID] += |
| 100 | + nV & devRhoReffb[patchID]; |
| 101 | + |
| 102 | + // Write the stress to the preCICE buffer |
| 103 | + // For every cell of the patch |
| 104 | + forAll(Stress_->boundaryFieldRef()[patchID], i) |
| 105 | + { |
| 106 | + // Copy the stress into the buffer |
| 107 | + // x-dimension |
| 108 | + buffer[bufferIndex++] |
| 109 | + = |
| 110 | + Stress_->boundaryFieldRef()[patchID][i].x(); |
| 111 | + |
| 112 | + // y-dimension |
| 113 | + buffer[bufferIndex++] |
| 114 | + = |
| 115 | + Stress_->boundaryFieldRef()[patchID][i].y(); |
| 116 | + |
| 117 | + if(dim == 3) |
| 118 | + // z-dimension |
| 119 | + buffer[bufferIndex++] |
| 120 | + = |
| 121 | + Stress_->boundaryFieldRef()[patchID][i].z(); |
| 122 | + } |
| 123 | + } |
| 124 | +} |
| 125 | + |
| 126 | +void preciceAdapter::FSI::Stress::read(double * buffer, const unsigned int dim) |
| 127 | +{ |
| 128 | + /* TODO: Implement |
| 129 | + * We need two nested for-loops for each patch, |
| 130 | + * the outer for the locations and the inner for the dimensions. |
| 131 | + * See the preCICE readBlockVectorData() implementation. |
| 132 | + */ |
| 133 | + FatalErrorInFunction |
| 134 | + << "Reading stresses is not supported." |
| 135 | + << exit(FatalError); |
| 136 | +} |
| 137 | + |
| 138 | +preciceAdapter::FSI::Stress::~Stress() |
| 139 | +{ |
| 140 | + delete Stress_; |
| 141 | +} |
0 commit comments