1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 Tetrahedral Finite Element matrix member functions and operators
28 \*---------------------------------------------------------------------------*/
30 #include "PstreamReduceOps.H"
32 #include "tetFemMatrix.H"
33 #include "tetPointFields.H"
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 const label tetFemMatrix<Type>::fixFillIn = 4;
46 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 tetFemMatrix<Type>::tetFemMatrix
51 GeometricField<Type, tetPolyPatchField, tetPointMesh>& psi,
52 const dimensionSet& ds
55 lduMatrix(psi.mesh()),
58 source_(psi.size(), pTraits<Type>::zero),
59 boundaryConditionsSet_(false),
60 fixedEqns_(psi.mesh().lduAddr().size()/fixFillIn),
65 Info<< "tetFemMatrix<Type>(GeometricField<Type, tetPolyPatchField, "
66 << "tetPointMesh>&, const dimensionSet&) : "
67 << "constructing tetFemMatrix<Type> for field " << psi_.name()
74 tetFemMatrix<Type>::tetFemMatrix(const tetFemMatrix<Type>& tetFem)
79 dimensions_(tetFem.dimensions_),
80 source_(tetFem.source_),
81 boundaryConditionsSet_(false),
82 fixedEqns_(psi_.mesh().lduAddr().size()/fixFillIn),
87 Info<< "tetFemMatrix<Type>::tetFemMatrix(const tetFemMatrix<Type>&) : "
88 << "copying tetFemMatrix<Type> for field " << psi_.name()
95 tetFemMatrix<Type>::tetFemMatrix
97 GeometricField<Type, tetPolyPatchField, tetPointMesh>& psi,
101 lduMatrix(psi.mesh()),
105 boundaryConditionsSet_(false),
106 fixedEqns_(psi.mesh().lduAddr().size()/fixFillIn),
111 Info<< "tetFemMatrix<Type>(GeometricField<Type, tetPolyPatchField, "
112 << "tetPointMesh>&, Istream&) : "
113 << "constructing tetFemMatrix<Type> for field " << psi_.name()
120 tetFemMatrix<Type>::~tetFemMatrix()
124 Info<< "tetFemMatrix<Type>::~tetFemMatrix<Type>() : "
125 << "destroying tetFemMatrix<Type> for field " << psi_.name()
131 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
133 // Does the matrix need a reference level for solution
134 // template<class Type>
135 // bool tetFemMatrix<Type>::needReference()
137 // // Search all boundary conditions, if any are
138 // // fixed-value or mixed (Robin) do not set reference level for solution.
140 // static bool searched = false;
141 // static bool needRef = true;
145 // const BoundaryField<Type>& patchFields = psi_.boundaryField();
147 // forAll(patchFields, patchi)
149 // if (patchFields[patchi].fixesValue())
155 // reduce(needRef, andOp<bool>());
164 // Set reference level for solution
166 void tetFemMatrix<Type>::addConstraint
172 constraint<Type> cp(vertex, value);
174 if (!fixedEqns_.found(vertex))
176 fixedEqns_.insert(vertex, cp);
182 "void tetFemMatrix<Type>::addConstraint(const label vertex, "
184 ) << "Adding constraint on an already constrained point."
185 << " Point: " << vertex
188 fixedEqns_[vertex].combine(cp);
194 void tetFemMatrix<Type>::relax(const scalar alpha)
201 Field<Type>& S = source();
202 scalarField& D = diag();
204 // Store the current unrelaxed diagonal for use in updating the source
207 // Calculate the sum-mag off-diagonal from the interior faces
208 scalarField sumOff(D.size(), 0.0);
209 sumMagOffDiag(sumOff);
211 // Some treatment of coupled boundaries may be added here
214 // Ensure the matrix is diagonally dominant...
220 S += (D - D0)*psi_.internalField();
225 void tetFemMatrix<Type>::relax()
229 if (psi_.mesh().relax(psi_.name()))
231 alpha = psi_.mesh().relaxationFactor(psi_.name());
241 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
244 void tetFemMatrix<Type>::operator=(const tetFemMatrix<Type>& tetFem)
250 "tetFemMatrix<Type>::operator=(const tetFemMatrix<Type>&)"
251 ) << "attempted assignment to self"
252 << abort(FatalError);
255 if (&psi_ != &(tetFem.psi_))
259 "tetFemMatrix<Type>::operator=(const tetFemMatrix<Type>&)"
260 ) << "different fields"
261 << abort(FatalError);
264 lduMatrix::operator=(tetFem);
265 source_ = tetFem.source_;
266 boundaryConditionsSet_ = false;
272 void tetFemMatrix<Type>::operator=(const tmp<tetFemMatrix<Type> >& ttetFem)
274 operator=(ttetFem());
280 void tetFemMatrix<Type>::negate()
288 void tetFemMatrix<Type>::operator+=(const tetFemMatrix<Type>& tetFem)
290 checkMethod(*this, tetFem, "+=");
292 dimensions_ += tetFem.dimensions_;
293 lduMatrix::operator+=(tetFem);
294 source_ += tetFem.source_;
299 void tetFemMatrix<Type>::operator+=(const tmp<tetFemMatrix<Type> >& ttetFem)
301 operator+=(ttetFem());
307 void tetFemMatrix<Type>::operator+=
309 const GeometricField<Type, elementPatchField, elementMesh>& su
312 checkMethod(*this, su, "+=");
313 source() -= distributeField(su.internalField());
318 void tetFemMatrix<Type>::operator+=
320 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu
329 void tetFemMatrix<Type>::operator-=(const tetFemMatrix<Type>& tetFem)
331 checkMethod(*this, tetFem, "+=");
333 dimensions_ -= tetFem.dimensions_;
334 lduMatrix::operator-=(tetFem);
335 source_ -= tetFem.source_;
340 void tetFemMatrix<Type>::operator-=(const tmp<tetFemMatrix<Type> >& ttetFem)
342 operator-=(ttetFem());
348 void tetFemMatrix<Type>::operator-=
350 const GeometricField<Type, elementPatchField, elementMesh>& su
353 checkMethod(*this, su, "-=");
354 source() += distributeField(su.internalField());
359 void tetFemMatrix<Type>::operator-=
361 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu
370 void tetFemMatrix<Type>::operator+=
372 const dimensioned<Type>& su
375 checkMethod(*this, su, "+=");
376 source() -= distributeField(Field<Type>(psi.mesh().nCells(), su.value()));
381 void tetFemMatrix<Type>::operator-=
383 const dimensioned<Type>& su
386 checkMethod(*this, su, "-=");
387 source() += distributeField(Field<Type>(psi.mesh().nCells(), su.value()));
392 void tetFemMatrix<Type>::operator*=
394 const dimensioned<scalar>& ds
397 dimensions_ *= ds.dimensions();
398 lduMatrix::operator*=(ds.value());
399 source_ *= ds.value();
403 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
408 const tetFemMatrix<Type>& tetFem1,
409 const tetFemMatrix<Type>& tetFem2,
413 if (&tetFem1.psi() != &tetFem2.psi())
417 "checkMethod(const tetFemMatrix<Type>&, "
418 "const tetFemMatrix<Type>&) : "
419 ) << "incompatible fields for operation "
421 << "[" << tetFem1.psi().name() << "] "
423 << " [" << tetFem1.psi().name() << "]"
424 << abort(FatalError);
427 if (dimensionSet::debug && tetFem1.dimensions() != tetFem2.dimensions())
431 "checkMethod(const tetFemMatrix<Type>&, "
432 "const tetFemMatrix<Type>&) : "
433 ) << "incompatible dimensions for operation "
435 << "[" << tetFem1.psi().name() << tetFem1.dimensions()/dimVolume
438 << " [" << tetFem1.psi().name() << tetFem2.dimensions()/dimVolume
440 << abort(FatalError);
448 const tetFemMatrix<Type>& tetFem,
449 const GeometricField<Type, elementPatchField, elementMesh>& vf,
456 && tetFem.dimensions()/dimVolume != vf.dimensions()
461 "checkMethod(const tetFemMatrix<Type>&, "
462 "const GeometricField<Type, elementPatchField, "
464 ) << "incompatible dimensions for operation "
466 << "[" << tetFem.psi().name() << tetFem.dimensions()/dimVolume
469 << " [" << tetFem.psi().name() << vf.dimensions() << " ]"
470 << abort(FatalError);
478 const tetFemMatrix<Type>& tetFem,
479 const dimensioned<Type>& dt,
486 && tetFem.dimensions()/dimVolume != dt.dimensions()
491 "checkMethod(const tetFemMatrix<Type>&, "
492 "const dimensioned<Type>&) : "
493 ) << "incompatible dimensions for operation "
495 << "[" << tetFem.psi().name() << tetFem.dimensions()/dimVolume
498 << " [" << dt.name() << dt.dimensions() << " ]"
499 << abort(FatalError);
505 lduSolverPerformance solve
507 tetFemMatrix<Type>& tetFem,
508 Istream& solverControls
511 return tetFem.solve(solverControls);
515 lduSolverPerformance solve
517 const tmp<tetFemMatrix<Type> >& ttetFem,
518 Istream& solverControls
521 lduSolverPerformance solverPerf =
522 const_cast<tetFemMatrix<Type>&>(ttetFem()).solve(solverControls);
531 lduSolverPerformance solve(tetFemMatrix<Type>& tetFem)
533 return tetFem.solve();
538 lduSolverPerformance solve(const tmp<tetFemMatrix<Type> >& ttetFem)
540 lduSolverPerformance solverPerf =
541 const_cast<tetFemMatrix<Type>&>(ttetFem()).solve();
548 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
551 tmp<tetFemMatrix<Type> > operator+
553 const tetFemMatrix<Type>& A,
554 const tetFemMatrix<Type>& B
557 checkMethod(A, B, "+");
558 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
565 tmp<tetFemMatrix<Type> > operator+
567 const tmp<tetFemMatrix<Type> >& tA,
568 const tetFemMatrix<Type>& B
571 checkMethod(tA(), B, "+");
572 tmp<tetFemMatrix<Type> > tC(tA.ptr());
579 tmp<tetFemMatrix<Type> > operator+
581 const tetFemMatrix<Type>& A,
582 const tmp<tetFemMatrix<Type> >& tB
585 checkMethod(A, tB(), "+");
586 tmp<tetFemMatrix<Type> > tC(tB.ptr());
593 tmp<tetFemMatrix<Type> > operator+
595 const tmp<tetFemMatrix<Type> >& tA,
596 const tmp<tetFemMatrix<Type> >& tB
599 checkMethod(tA(), tB(), "+");
600 tmp<tetFemMatrix<Type> > tC(tA.ptr());
608 tmp<tetFemMatrix<Type> > operator-
610 const tetFemMatrix<Type>& A
613 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
620 tmp<tetFemMatrix<Type> > operator-
622 const tmp<tetFemMatrix<Type> >& tA
625 tmp<tetFemMatrix<Type> > tC(tA.ptr());
632 tmp<tetFemMatrix<Type> > operator-
634 const tetFemMatrix<Type>& A,
635 const tetFemMatrix<Type>& B
638 checkMethod(A, B, "-");
639 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
646 tmp<tetFemMatrix<Type> > operator-
648 const tmp<tetFemMatrix<Type> >& tA,
649 const tetFemMatrix<Type>& B
652 checkMethod(tA(), B, "-");
653 tmp<tetFemMatrix<Type> > tC(tA.ptr());
660 tmp<tetFemMatrix<Type> > operator-
662 const tetFemMatrix<Type>& A,
663 const tmp<tetFemMatrix<Type> >& tB
666 checkMethod(A, tB(), "-");
667 tmp<tetFemMatrix<Type> > tC(tB.ptr());
675 tmp<tetFemMatrix<Type> > operator-
677 const tmp<tetFemMatrix<Type> >& tA,
678 const tmp<tetFemMatrix<Type> >& tB
681 checkMethod(tA(), tB(), "-");
682 tmp<tetFemMatrix<Type> > tC(tA.ptr());
690 tmp<tetFemMatrix<Type> > operator==
692 const tetFemMatrix<Type>& A,
693 const tetFemMatrix<Type>& B
696 checkMethod(A, B, "==");
702 tmp<tetFemMatrix<Type> > operator==
704 const tmp<tetFemMatrix<Type> >& tA,
705 const tetFemMatrix<Type>& B
708 checkMethod(tA(), B, "==");
714 tmp<tetFemMatrix<Type> > operator==
716 const tetFemMatrix<Type>& A,
717 const tmp<tetFemMatrix<Type> >& tB
720 checkMethod(A, tB(), "==");
726 tmp<tetFemMatrix<Type> > operator==
728 const tmp<tetFemMatrix<Type> >& tA,
729 const tmp<tetFemMatrix<Type> >& tB
732 checkMethod(tA(), tB(), "==");
738 tmp<tetFemMatrix<Type> > operator+
740 const tetFemMatrix<Type>& A,
741 const GeometricField<Type, elementPatchField, elementMesh>& su
744 checkMethod(A, su, "+");
745 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
751 tmp<tetFemMatrix<Type> > operator+
753 const tmp<tetFemMatrix<Type> >& tA,
754 const GeometricField<Type, elementPatchField, elementMesh>& su
757 checkMethod(tA(), su, "+");
758 tmp<tetFemMatrix<Type> > tC(tA.ptr());
764 tmp<tetFemMatrix<Type> > operator+
766 const tetFemMatrix<Type>& A,
767 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu
770 checkMethod(A, tsu(), "+");
771 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
779 tmp<tetFemMatrix<Type> > operator+
781 const tmp<tetFemMatrix<Type> >& tA,
782 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu
785 checkMethod(tA(), tsu(), "+");
786 tmp<tetFemMatrix<Type> > tC(tA.ptr());
793 tmp<tetFemMatrix<Type> > operator+
795 const GeometricField<Type, elementPatchField, elementMesh>& su,
796 const tetFemMatrix<Type>& A
799 checkMethod(A, su, "+");
800 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
806 tmp<tetFemMatrix<Type> > operator+
808 const GeometricField<Type, elementPatchField, elementMesh>& su,
809 const tmp<tetFemMatrix<Type> >& tA
812 checkMethod(tA(), su, "+");
813 tmp<tetFemMatrix<Type> > tC(tA.ptr());
819 tmp<tetFemMatrix<Type> > operator+
821 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu,
822 const tetFemMatrix<Type>& A
825 checkMethod(A, tsu(), "+");
826 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
833 tmp<tetFemMatrix<Type> > operator+
835 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu,
836 const tmp<tetFemMatrix<Type> >& tA
839 checkMethod(tA(), tsu(), "+");
840 tmp<tetFemMatrix<Type> > tC(tA.ptr());
848 tmp<tetFemMatrix<Type> > operator-
850 const tetFemMatrix<Type>& A,
851 const GeometricField<Type, elementPatchField, elementMesh>& su
854 checkMethod(A, su, "-");
855 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
861 tmp<tetFemMatrix<Type> > operator-
863 const tmp<tetFemMatrix<Type> >& tA,
864 const GeometricField<Type, elementPatchField, elementMesh>& su
867 checkMethod(tA(), su, "-");
868 tmp<tetFemMatrix<Type> > tC(tA.ptr());
874 tmp<tetFemMatrix<Type> > operator-
876 const tetFemMatrix<Type>& A,
877 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu
880 checkMethod(A, tsu(), "-");
881 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
888 tmp<tetFemMatrix<Type> > operator-
890 const tmp<tetFemMatrix<Type> >& tA,
891 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu
894 checkMethod(tA(), tsu(), "-");
895 tmp<tetFemMatrix<Type> > tC(tA.ptr());
903 tmp<tetFemMatrix<Type> > operator-
905 const GeometricField<Type, elementPatchField, elementMesh>& su,
906 const tetFemMatrix<Type>& A
909 checkMethod(A, su, "-");
910 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
918 tmp<tetFemMatrix<Type> > operator-
920 const GeometricField<Type, elementPatchField, elementMesh>& su,
921 const tmp<tetFemMatrix<Type> >& tA
924 checkMethod(tA(), su, "-");
925 tmp<tetFemMatrix<Type> > tC(tA.ptr());
932 tmp<tetFemMatrix<Type> > operator-
934 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu,
935 const tetFemMatrix<Type>& A
938 checkMethod(A, tsu(), "-");
939 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
948 tmp<tetFemMatrix<Type> > operator-
950 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu,
951 const tmp<tetFemMatrix<Type> >& tA
954 checkMethod(tA(), tsu(), "-");
955 tmp<tetFemMatrix<Type> > tC(tA.ptr());
964 tmp<tetFemMatrix<Type> > operator+
966 const tetFemMatrix<Type>& A,
967 const dimensioned<Type>& su
970 checkMethod(A, su, "+");
971 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
978 tmp<tetFemMatrix<Type> > operator+
980 const tmp<tetFemMatrix<Type> >& tA,
981 const dimensioned<Type>& su
984 checkMethod(tA(), su, "+");
985 tmp<tetFemMatrix<Type> > tC(tA.ptr());
992 tmp<tetFemMatrix<Type> > operator+
994 const dimensioned<Type>& su,
995 const tetFemMatrix<Type>& A
998 checkMethod(A, su, "+");
999 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
1005 template<class Type>
1006 tmp<tetFemMatrix<Type> > operator+
1008 const dimensioned<Type>& su,
1009 const tmp<tetFemMatrix<Type> >& tA
1012 checkMethod(tA(), su, "+");
1013 tmp<tetFemMatrix<Type> > tC(tA.ptr());
1019 template<class Type>
1020 tmp<tetFemMatrix<Type> > operator-
1022 const tetFemMatrix<Type>& A,
1023 const dimensioned<Type>& su
1026 checkMethod(A, su, "-");
1027 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
1033 template<class Type>
1034 tmp<tetFemMatrix<Type> > operator-
1036 const tmp<tetFemMatrix<Type> >& tA,
1037 const dimensioned<Type>& su
1040 checkMethod(tA(), su, "-");
1041 tmp<tetFemMatrix<Type> > tC(tA.ptr());
1047 template<class Type>
1048 tmp<tetFemMatrix<Type> > operator-
1050 const dimensioned<Type>& su,
1051 const tetFemMatrix<Type>& A
1054 checkMethod(A, su, "-");
1055 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
1062 template<class Type>
1063 tmp<tetFemMatrix<Type> > operator-
1065 const dimensioned<Type>& su,
1066 const tmp<tetFemMatrix<Type> >& tA
1069 checkMethod(tA(), su, "-");
1070 tmp<tetFemMatrix<Type> > tC(tA.ptr());
1077 template<class Type>
1078 tmp<tetFemMatrix<Type> > operator==
1080 const tetFemMatrix<Type>& A,
1081 const GeometricField<Type, elementPatchField, elementMesh>& su
1084 checkMethod(A, su, "==");
1085 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
1090 template<class Type>
1091 tmp<tetFemMatrix<Type> > operator==
1093 const tmp<tetFemMatrix<Type> >& tA,
1094 const GeometricField<Type, elementPatchField, elementMesh>& su
1097 checkMethod(tA(), su, "==");
1098 tmp<tetFemMatrix<Type> > tC(tA.ptr());
1103 template<class Type>
1104 tmp<tetFemMatrix<Type> > operator==
1106 const tetFemMatrix<Type>& A,
1107 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu
1110 checkMethod(A, tsu(), "==");
1111 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
1117 template<class Type>
1118 tmp<tetFemMatrix<Type> > operator==
1120 const tmp<tetFemMatrix<Type> >& tA,
1121 const tmp<GeometricField<Type, elementPatchField, elementMesh> >& tsu
1124 checkMethod(tA(), tsu(), "==");
1125 tmp<tetFemMatrix<Type> > tC(tA.ptr());
1132 template<class Type>
1133 tmp<tetFemMatrix<Type> > operator==
1135 const tetFemMatrix<Type>& A,
1136 const dimensioned<Type>& su
1139 checkMethod(A, su, "==");
1140 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
1146 template<class Type>
1147 tmp<tetFemMatrix<Type> > operator==
1149 const tmp<tetFemMatrix<Type> >& tA,
1150 const dimensioned<Type>& su
1153 checkMethod(tA(), su, "==");
1154 tmp<tetFemMatrix<Type> > tC(tA.ptr());
1160 template<class Type>
1161 tmp<tetFemMatrix<Type> > operator*
1163 const dimensioned<scalar>& ds,
1164 const tetFemMatrix<Type>& A
1167 tmp<tetFemMatrix<Type> > tC(new tetFemMatrix<Type>(A));
1173 template<class Type>
1174 tmp<tetFemMatrix<Type> > operator*
1176 const dimensioned<scalar>& ds,
1177 const tmp<tetFemMatrix<Type> >& tA
1180 tmp<tetFemMatrix<Type> > tC(tA.ptr());
1186 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1188 template<class Type>
1189 Ostream& operator<<(Ostream& os, const tetFemMatrix<Type>& tetFem)
1191 os << static_cast<const lduMatrix&>(tetFem) << nl
1192 << tetFem.dimensions_ << nl
1193 << tetFem.source_ << endl;
1195 os.check("Ostream& operator<<(Ostream&, tetFemMatrix<Type>&");
1201 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1203 } // End namespace Foam
1205 // ************************************************************************* //