42 const word& hilbertSpacePOD,
43 const double& weightBC,
45 const double& weightH1)
47 Eigen::MatrixXd matrix_dot_product = Eigen::MatrixXd::Zero(v.size(),w.size());
48 if (hilbertSpacePOD ==
"L2")
52 else if (hilbertSpacePOD ==
"dL2"){
54 V = V.array().inverse();
59 Info <<
"Error: hilbertSpacePOD " << hilbertSpacePOD <<
" is not valid." << endl;
60 Info <<
"NOT CODED YET : dot_product_POD is available for L2 only." << endl;
63 return matrix_dot_product;
66template Eigen::MatrixXd
dot_product_POD(PtrList<volTensorField>& v, PtrList<volTensorField>& w,
67 const word& hilbertSpacePOD,
68 const double& weightBC,
70 const double& weightH1);
71template Eigen::MatrixXd
dot_product_POD(PtrList<volVectorField>& v, PtrList<volVectorField>& w,
72 const word& hilbertSpacePOD,
73 const double& weightBC,
75 const double& weightH1);
76template Eigen::MatrixXd
dot_product_POD(PtrList<volScalarField>& v, PtrList<volScalarField>& w,
77 const word& hilbertSpacePOD,
78 const double& weightBC,
80 const double& weightH1);
85 const word& hilbertSpacePOD,
86 const double& weightBC,
88 const double& weightH1)
91 if (hilbertSpacePOD ==
"L2" || hilbertSpacePOD ==
"dL2")
95 else if (hilbertSpacePOD ==
"L2wBC")
99 else if (hilbertSpacePOD ==
"H1")
103 else if (hilbertSpacePOD ==
"wH1")
109 Info <<
"Error: hilbertSpacePOD " << hilbertSpacePOD <<
" is not valid." << endl;
110 Info <<
"dot_product_POD is available for L2, L2wBC, H1 and wH1 only." << endl;
116double dot_product_POD(
const volVectorField& v,
const volVectorField& w,
const word& hilbertSpacePOD,
const double& weightBC,
const word& patchBC,
const double& weightH1)
119 if (hilbertSpacePOD ==
"L2")
123 else if (hilbertSpacePOD ==
"L2wBC")
127 else if (hilbertSpacePOD ==
"H1")
131 else if (hilbertSpacePOD ==
"wH1")
137 Info <<
"Error: hilbertSpacePOD " << hilbertSpacePOD <<
" is not valid." << endl;
138 Info <<
"dot_product_POD is available for L2, L2wBC, H1 and wH1 only." << endl;
145 const word& hilbertSpacePOD,
146 const double& weightBC,
148 const double& weightH1)
151 if (hilbertSpacePOD ==
"L2")
155 else if (hilbertSpacePOD ==
"L2wBC")
159 else if ((hilbertSpacePOD ==
"H1")||(hilbertSpacePOD ==
"wH1"))
161 Info <<
"Error : dot_product_POD cannot be computed between volTensorFields with the hilbertSpacePOD =" <<hilbertSpacePOD <<
" ." << endl;
166 Info <<
"Error: hilbertSpacePOD " << hilbertSpacePOD <<
" is not valid." << endl;
167 Info <<
"dot_product_POD is available for L2, L2wBC, H1 and wH1 only." << endl;
179template double dot_product_H1(
const volVectorField& v,
const volVectorField& w,
const double& weightH1);
180template double dot_product_H1(
const volScalarField& v,
const volScalarField& w,
const double& weightH1);
184 return fvc::domainIntegrate(v & w).value();
190 return fvc::domainIntegrate(v * w).value();
196 return fvc::domainIntegrate(v && w).value();
200double dot_product_patch(
const Eigen::VectorXd& f1BC_i,
const Eigen::VectorXd& f2BC_i,
const scalarField& AreaFace,
const int& d)
202 double dot_prod_patch=0.;
205 for (label k = 0; k < f1BC_i.size()/d; k++)
209 for (label i=0;i<d;i++)
211 productBC+=f1BC_i(k+i*f1BC_i.size()/d) * f2BC_i(k+i*f1BC_i.size()/d);
213 dot_prod_patch+=productBC* AreaFace[k] * dx;
215 return dot_prod_patch;
224 double dot_prod_boundary=0.;
226 int NBC = f1.boundaryField().size();
230 label ind = f1.mesh().boundaryMesh().findPatchID(patchBC);
238 for (label i=0;i<NBC;i++)
249 for (label g = 0; g < l.size(); g++)
252 scalarField AreaFace = f1.mesh().magSf().boundaryField()[l[g]];
256 return dot_prod_boundary;
258template double dot_product_boundary(
const volTensorField& v,
const volTensorField& w,
const word& patchBC);
259template double dot_product_boundary(
const volVectorField& v,
const volVectorField& w,
const word& patchBC);
260template double dot_product_boundary(
const volScalarField& v,
const volScalarField& w,
const word& patchBC);
276template double dot_product_L2wBC(
const volTensorField& v,
const volTensorField& w,
const double& weightBC,
const word& patchBC);
277template double dot_product_L2wBC(
const volVectorField& v,
const volVectorField& w,
const double& weightBC,
const word& patchBC);
278template double dot_product_L2wBC(
const volScalarField& v,
const volScalarField& w,
const double& weightBC,
const word& patchBC);
281double norm_L2wBC(
const T& v,
const double& weightBC,
const word& patchBC)
286template double norm_L2wBC(
const volTensorField& v,
const double& weightBC,
const word& patchBC);
287template double norm_L2wBC(
const volVectorField& v,
const double& weightBC,
const word& patchBC);
288template double norm_L2wBC(
const volScalarField& v,
const double& weightBC,
const word& patchBC);
291double norm_POD(
const T& v,
const word& hilbertSpacePOD,
const double& weightBC,
const word& patchBC,
const double& weightH1)
293 return std::sqrt(
dot_product_POD(v,v, hilbertSpacePOD, weightBC, patchBC, weightH1));
296template double norm_POD(
const volVectorField& v,
const word& hilbertSpacePOD,
const double& weightBC,
const word& patchBC,
const double& weightH1);
297template double norm_POD(
const volScalarField& v,
const word& hilbertSpacePOD,
const double& weightBC,
const word& patchBC,
const double& weightH1);
306template double L2Norm(
const volTensorField& v);
307template double L2Norm(
const volVectorField& v);
308template double L2Norm(
const volScalarField& v);
309template double L2Norm(
const volTensorField v);
310template double L2Norm(
const volVectorField v);
311template double L2Norm(
const volScalarField v);
312template double L2Norm(
const tmp<volTensorField> v);
313template double L2Norm(
const tmp<volVectorField> v);
314template double L2Norm(
const tmp<volScalarField> v);
318double LinfNorm(GeometricField<scalar, fvPatchField, volMesh>& field)
321 a = Foam::max(Foam::sqrt(field.internalField() *
322 field.internalField())).value();
327double LinfNorm(GeometricField<vector, fvPatchField, volMesh>& field)
330 Info <<
"LinfNorm(GeometricField<vector, fvPatchField, volMesh>& field) is still to be implemented"
337double H1Seminorm(GeometricField<scalar, fvPatchField, volMesh>& field)
340 a = Foam::sqrt(fvc::domainIntegrate(fvc::grad(field) & fvc::grad(
346double H1Seminorm(GeometricField<vector, fvPatchField, volMesh>& field)
349 a = Foam::sqrt(fvc::domainIntegrate(fvc::grad(field)
350 && fvc::grad(field)).value());
354template<
class Type,
template<
class>
class PatchField,
class GeoMesh>
355double frobNorm(GeometricField<Type, PatchField, GeoMesh>& field)
362template double frobNorm(GeometricField<scalar, fvPatchField, volMesh>& field);
363template double frobNorm(GeometricField<scalar, fvsPatchField, surfaceMesh>& field);
364template double frobNorm(GeometricField<vector, fvPatchField, volMesh>& field);
371 label patchID = mesh.boundaryMesh().findPatchID(patch);
372 const polyPatch& cPatch = mesh.boundaryMesh()[patchID];
374 const labelUList& faceCells = cPatch.faceCells();
375 forAll(cPatch, faceI)
378 label faceOwner = faceCells[faceI] ;
379 scalar faceArea = mesh.magSf().boundaryField()[patchID][faceI];
380 L2 += faceArea * field[faceOwner] * field[faceOwner];
383 return Foam::sqrt(L2);
387 List<scalar>& field2, word patch)
389 M_Assert(field1.size() == field2.size(),
390 "The two fields do not have the same size, code will abort");
393 label patchID = mesh.boundaryMesh().findPatchID(patch);
394 const polyPatch& cPatch = mesh.boundaryMesh()[patchID];
395 M_Assert(field1.size() == cPatch.size(),
396 "The filds must have the same size of the patch, code will abort");
397 forAll(cPatch, faceI)
399 scalar faceArea = mesh.magSf().boundaryField()[patchID][faceI];
400 L2 += faceArea * field1[faceI] * field2[faceI];
411 label patchID = mesh.boundaryMesh().findPatchID(patch);
412 const polyPatch& cPatch = mesh.boundaryMesh()[patchID];
414 const labelUList& faceCells = cPatch.faceCells();
415 forAll(cPatch, faceI)
417 label faceOwner = faceCells[faceI] ;
421 Linf = std::abs(field[faceOwner]);
423 else if (std::abs(field[faceOwner]) > Linf)
425 Linf = std::abs(field[faceOwner]);
437 label patchID = mesh.boundaryMesh().findPatchID(patch);
438 const polyPatch& cPatch = mesh.boundaryMesh()[patchID];
440 const labelUList& faceCells = cPatch.faceCells();
441 forAll(cPatch, faceI)
444 label faceOwner = faceCells[faceI] ;
445 scalar faceArea = mesh.magSf().boundaryField()[patchID][faceI];
446 integral += faceArea * field[faceOwner];
457 label patchID = mesh.boundaryMesh().findPatchID(patch);
458 const polyPatch& cPatch = mesh.boundaryMesh()[patchID];
460 const labelUList& faceCells = cPatch.faceCells();
461 int patchSize = mesh.magSf().boundaryField()[patchID].size();
462 std::string message =
"The input list (size = " + std::to_string(field.size())
463 +
") must have the same size of the patch mesh (size = "
464 + std::to_string(patchSize) +
")";
465 M_Assert( patchSize == field.size(), message.c_str());
466 forAll(cPatch, faceI)
469 label faceOwner = faceCells[faceI] ;
470 scalar faceArea = mesh.magSf().boundaryField()[patchID][faceI];
471 integral += faceArea * field[faceI];
Header file of the ITHACAnorm file.
static List< Eigen::VectorXd > field2EigenBC(GeometricField< scalar, PatchField, GeoMesh > &field)
Convert an OpenFOAM scalar field to a List of Eigen Vectors, one for each boundary.
static Eigen::MatrixXd field2Eigen(GeometricField< Type, PatchField, GeoMesh > &field)
Convert a vector OpenFOAM field into an Eigen Vector.
Namespace to implement some useful assign operation of OF fields.
double norm_L2wBC(const T &v, const double &weightBC, const word &patchBC)
Compute the norm using the L2 dot product of v at the boundaries.
int dimensionField(const volTensorField &v)
Return the dimension of a volTensorField.
double LinfNormOnPatch(fvMesh &mesh, volScalarField &field, word patch)
Evaluate the Linf norm of a field on a boundary patch.
double dot_product_boundary(const T &v, const T &w, const word &patchBC)
Perform the L2 dot product of v and w at a given boundary.
Eigen::MatrixXd dot_product_POD(PtrList< T > &v, PtrList< T > &w, const word &hilbertSpacePOD, const double &weightBC, const word &patchBC, const double &weightH1)
Perform the dot product of two PtrList of type T.
double integralOnPatch(fvMesh &mesh, volScalarField &field, word patch)
Evaluate the integral on a patch.
double L2normOnPatch(fvMesh &mesh, volScalarField &field, word patch)
Evaluate the L2 norm of a field on a boundary patch.
double frobNorm(GeometricField< Type, PatchField, GeoMesh > &field)
Evaluate the Frobenius norm of a field.
Eigen::VectorXd getMassMatrixFV(GeometricField< Type, PatchField, GeoMesh > &snapshot)
Gets a vector containing the volumes of each cell of the mesh.
double dot_product_patch(const Eigen::VectorXd &f1BC_i, const Eigen::VectorXd &f2BC_i, const scalarField &AreaFace, const int &d)
Perform the L2 dot product of v and w at a given boundary patch.
double L2Norm(const T v)
Compute the L2 norm of v.
Eigen::MatrixXd getMassMatrix(PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, label Nmodes, bool consider_volumes)
Gets the mass matrix using the eigen routine.
double dot_product_L2(const volVectorField &v, const volVectorField &w)
Perform the L2 dot product of v and w.
double norm_POD(const T &v, const word &hilbertSpacePOD, const double &weightBC, const word &patchBC, const double &weightH1)
Compute the norm of v.
double dot_product_H1(const T &v, const T &w, const double &weightH1)
Perform the H1 dot product of v and w.
double L2productOnPatch(fvMesh &mesh, List< scalar > &field1, List< scalar > &field2, word patch)
Evaluate the L2 inner product between two scalarLists.
double dot_product_L2wBC(const T &v, const T &w, const double &weightBC, const word &patchBC)
Perform the L2 dot product of v and w at the boundaries.