23#ifndef DUMUX_FVMPFAL2D_TRANSMISSIBILITYCALCULATOR_HH
24#define DUMUX_FVMPFAL2D_TRANSMISSIBILITYCALCULATOR_HH
42template<
class TypeTag>
49 dim = GridView::dimension, dimWorld = GridView::dimensionworld
55 using Element =
typename GridView::template Codim<0>::Entity;
57 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
58 using DimMatrix = Dune::FieldMatrix<Scalar, dim, dim>;
60 using DimVector = Dune::FieldVector<Scalar, dim>;
78 InteractionVolume& interactionVolume,
79 std::vector<DimVector >& lambda,
80 int idx1,
int idx2,
int idx3,
int idx4);
84 InteractionVolume& interactionVolume,
85 std::vector<DimVector >& lambda,
86 int idx1,
int idx2,
int idx3);
90 InteractionVolume& interactionVolume,
91 std::vector<DimVector >& lambda,
92 int idx1,
int idx2,
int idx3);
100 problem_(problem), R_(0)
104 DUNE_THROW(Dune::NotImplemented,
"Dimension not supported!");
135template<
class TypeTag>
139 std::vector<DimVector >& lambda,
140 int idx1,
int idx2,
int idx3,
int idx4)
147 if (element3 == element4 && element1.level() != element2.level())
149 return noTransmissibility;
153 const GlobalPosition& globalPos1 = element1.geometry().center();
154 const GlobalPosition& globalPos2 = element2.geometry().center();
155 const GlobalPosition& globalPos3 = element3.geometry().center();
156 const GlobalPosition& globalPos4 = element4.geometry().center();
160 const DimMatrix& K1 = problem_.spatialParams().intrinsicPermeability(element1);
161 const DimMatrix& K2 = problem_.spatialParams().intrinsicPermeability(element2);
162 const DimMatrix& K3 = problem_.spatialParams().intrinsicPermeability(element3);
163 const DimMatrix& K4 = problem_.spatialParams().intrinsicPermeability(element4);
165 const GlobalPosition& globalPosFace12 = interactionVolume.
getFacePosition(idx1, 0);
166 const GlobalPosition& globalPosFace23 = interactionVolume.
getFacePosition(idx2, 0);
170 R_.mv(globalPosFace12 - globalPos2, nu1R1);
173 R_.mv(globalPos2 - globalPosFace23, nu2R1);
176 R_.mv(globalPosFace23 - globalPos3, nu3R1);
179 R_.mv(globalPos3 - globalPosCenter, nu4R1);
182 R_.mv(globalPosCenter - globalPos1, nu5R1);
185 R_.mv(globalPos1 - globalPosFace12, nu6R1);
188 R_.mv(globalPosCenter - globalPos2, nu7R1);
192 R_.mv(nu2R1, Rnu2R1);
193 Scalar T1R1 = nu1R1 * Rnu2R1;
196 R_.mv(nu4R1, Rnu4R1);
197 Scalar T2R1 = nu3R1 * Rnu4R1;
200 R_.mv(nu6R1, Rnu6R1);
201 Scalar T3R1 = nu5R1 * Rnu6R1;
204 DimVector K2nu1R1(0);
205 K2.mv(nu1R1, K2nu1R1);
206 DimVector K2nu2R1(0);
207 K2.mv(nu2R1, K2nu2R1);
208 DimVector K4nu3R1(0);
209 K3.mv(nu3R1, K4nu3R1);
210 DimVector K4nu4R1(0);
211 K3.mv(nu4R1, K4nu4R1);
212 DimVector K1nu5R1(0);
213 K1.mv(nu5R1, K1nu5R1);
214 DimVector K1nu6R1(0);
215 K1.mv(nu6R1, K1nu6R1);
218 R_.mv(nu1R1, Rnu1R1);
220 DimVector &outerNormaln1R1 = interactionVolume.
getNormal(idx2, 0);
221 DimVector &outerNormaln2 = interactionVolume.
getNormal(idx1, 0);
223 Scalar omega111R1 = lambda[idx2][0] * (outerNormaln1R1 * K2nu1R1) * interactionVolume.
getFaceArea(idx2, 0) / T1R1;
224 Scalar omega112R1 = lambda[idx2][0] * (outerNormaln1R1 * K2nu2R1) * interactionVolume.
getFaceArea(idx2, 0) / T1R1;
225 Scalar omega211R1 = lambda[idx2][1] * (outerNormaln2 * K2nu1R1) * interactionVolume.
getFaceArea(idx2, 1) / T1R1;
226 Scalar omega212R1 = lambda[idx2][1] * (outerNormaln2 * K2nu2R1) * interactionVolume.
getFaceArea(idx2, 1) / T1R1;
227 Scalar omega123R1 = lambda[idx3][1] * (outerNormaln1R1 * K4nu3R1) * interactionVolume.
getFaceArea(idx3, 1) / T2R1;
228 Scalar omega124R1 = lambda[idx3][1] * (outerNormaln1R1 * K4nu4R1) * interactionVolume.
getFaceArea(idx3, 1) / T2R1;
229 Scalar omega235R1 = lambda[idx1][0] * (outerNormaln2 * K1nu5R1) * interactionVolume.
getFaceArea(idx1, 0) / T3R1;
230 Scalar omega236R1 = lambda[idx1][0] * (outerNormaln2 * K1nu6R1) * interactionVolume.
getFaceArea(idx1, 0) / T3R1;
231 Scalar chi711R1 = (nu7R1 * Rnu1R1) / T1R1;
232 Scalar chi712R1 = (nu7R1 * Rnu2R1) / T1R1;
235 DimMatrix C(0), A(0);
236 Dune::FieldMatrix<Scalar, dim, 2 * dim - dim + 1> D(0), B(0);
239 C[0][0] = -omega111R1;
240 C[0][1] = -omega112R1;
241 C[1][0] = -omega211R1;
242 C[1][1] = -omega212R1;
244 D[0][0] = omega111R1 + omega112R1;
245 D[1][0] = omega211R1 + omega212R1;
247 A[0][0] = omega111R1 - omega124R1 - omega123R1 * chi711R1;
248 A[0][1] = omega112R1 - omega123R1 * chi712R1;
249 A[1][0] = omega211R1 - omega236R1 * chi711R1;
250 A[1][1] = omega212R1 - omega235R1 - omega236R1 * chi712R1;
252 B[0][0] = omega111R1 + omega112R1 + omega123R1 * (1.0 - chi711R1 - chi712R1);
253 B[0][1] = -omega123R1 - omega124R1;
254 B[1][0] = omega211R1 + omega212R1 + omega236R1 * (1.0 - chi711R1 - chi712R1);
255 B[1][2] = -omega235R1 - omega236R1;
259 D += B.leftmultiply(C.rightmultiply(A));
260 Dune::FieldMatrix<Scalar, dim, 2 * dim - dim + 1> TR1(D);
263 const GlobalPosition& globalPosFace14 = interactionVolume.
getFacePosition(idx1, 1);
267 R_.mv(globalPosFace12 - globalPos1, nu1L1);
270 R_.mv(globalPos1 - globalPosFace14, nu2L1);
273 R_.mv(globalPosFace14 - globalPos4, nu3L1);
276 R_.mv(globalPos4 - globalPosCenter, nu4L1);
279 R_.mv(globalPosCenter - globalPos2, nu5L1);
282 R_.mv(globalPos2 - globalPosFace12, nu6L1);
285 R_.mv(globalPosCenter - globalPos1, nu7L1);
289 R_.mv(nu2L1, Rnu2L1);
290 Scalar T1L1 = nu1L1 * Rnu2L1;
293 R_.mv(nu4L1, Rnu4L1);
294 Scalar T2L1 = nu3L1 * Rnu4L1;
297 R_.mv(nu6L1, Rnu6L1);
298 Scalar T3L1 = nu5L1 * Rnu6L1;
301 DimVector K1nu1L1(0);
302 K1.mv(nu1L1, K1nu1L1);
303 DimVector K1nu2L1(0);
304 K1.mv(nu2L1, K1nu2L1);
305 DimVector K3nu3L1(0);
306 K4.mv(nu3L1, K3nu3L1);
307 DimVector K3nu4L1(0);
308 K4.mv(nu4L1, K3nu4L1);
309 DimVector K2nu5L1(0);
310 K2.mv(nu5L1, K2nu5L1);
311 DimVector K2nu6L1(0);
312 K2.mv(nu6L1, K2nu6L1);
315 R_.mv(nu1L1, Rnu1L1);
317 DimVector &outerNormaln1L1 = interactionVolume.
getNormal(idx1, 1);
319 Scalar omega111L1 = lambda[idx1][1] * (outerNormaln1L1 * K1nu1L1) * interactionVolume.
getFaceArea(idx1, 1) / T1L1;
320 Scalar omega112L1 = lambda[idx1][1] * (outerNormaln1L1 * K1nu2L1) * interactionVolume.
getFaceArea(idx1, 1) / T1L1;
321 Scalar omega211L1 = lambda[idx1][0] * (outerNormaln2 * K1nu1L1) * interactionVolume.
getFaceArea(idx1, 0) / T1L1;
322 Scalar omega212L1 = lambda[idx1][0] * (outerNormaln2 * K1nu2L1) * interactionVolume.
getFaceArea(idx1, 0) / T1L1;
323 Scalar omega123L1 = lambda[idx4][0] * (outerNormaln1L1 * K3nu3L1) * interactionVolume.
getFaceArea(idx4, 0) / T2L1;
324 Scalar omega124L1 = lambda[idx4][0] * (outerNormaln1L1 * K3nu4L1) * interactionVolume.
getFaceArea(idx4, 0) / T2L1;
325 Scalar omega235L1 = lambda[idx2][1] * (outerNormaln2 * K2nu5L1) * interactionVolume.
getFaceArea(idx2, 1) / T3L1;
326 Scalar omega236L1 = lambda[idx2][1] * (outerNormaln2 * K2nu6L1) * interactionVolume.
getFaceArea(idx2, 1) / T3L1;
327 Scalar chi711L1 = (nu7L1 * Rnu1L1) / T1L1;
328 Scalar chi712L1 = (nu7L1 * Rnu2L1) / T1L1;
337 C[0][0] = -omega111L1;
338 C[0][1] = -omega112L1;
339 C[1][0] = -omega211L1;
340 C[1][1] = -omega212L1;
342 D[0][0] = omega111L1 + omega112L1;
343 D[1][0] = omega211L1 + omega212L1;
345 A[0][0] = omega111L1 - omega124L1 - omega123L1 * chi711L1;
346 A[0][1] = omega112L1 - omega123L1 * chi712L1;
347 A[1][0] = omega211L1 - omega236L1 * chi711L1;
348 A[1][1] = omega212L1 - omega235L1 - omega236L1 * chi712L1;
350 B[0][0] = omega111L1 + omega112L1 + omega123L1 * (1.0 - chi711L1 - chi712L1);
351 B[0][1] = -omega123L1 - omega124L1;
352 B[1][0] = omega211L1 + omega212L1 + omega236L1 * (1.0 - chi711L1 - chi712L1);
353 B[1][2] = -omega235L1 - omega236L1;
357 D += B.leftmultiply(C.rightmultiply(A));
358 Dune::FieldMatrix<Scalar, dim, 2 * dim - dim + 1> TL1(D);
362 Scalar sR = abs(TR1[1][2] - TR1[1][0]);
363 Scalar sL = abs(TL1[1][0] - TL1[1][2]);
368 transmissibility = TR1;
369 return rightTriangle;
373 transmissibility = TL1;
392template<
class TypeTag>
396 std::vector<DimVector >& lambda,
397 int idx1,
int idx2,
int idx3)
403 if (element1.level() != element3.level())
405 return noTransmissibility;
409 const GlobalPosition& globalPos1 = element1.geometry().center();
410 const GlobalPosition& globalPos2 = element2.geometry().center();
411 const GlobalPosition& globalPos3 = element3.geometry().center();
415 const DimMatrix& K1 = problem_.spatialParams().intrinsicPermeability(element1);
416 const DimMatrix& K2 = problem_.spatialParams().intrinsicPermeability(element2);
417 const DimMatrix& K3 = problem_.spatialParams().intrinsicPermeability(element3);
419 const GlobalPosition& globalPosFace12 = interactionVolume.
getFacePosition(idx1, 0);
420 DimVector &outerNormaln2 = interactionVolume.
getNormal(idx1, 0);
423 DimMatrix C(0), A(0);
427 const GlobalPosition& globalPosFace14 = interactionVolume.
getFacePosition(idx1, 1);
431 R_.mv(globalPosFace12 - globalPos1, nu1L1);
434 R_.mv(globalPos1 - globalPosFace14, nu2L1);
437 R_.mv(globalPosFace14 - globalPos3, nu3L1);
440 R_.mv(globalPos3 - globalPosCenter, nu4L1);
443 R_.mv(globalPosCenter - globalPos2, nu5L1);
446 R_.mv(globalPos2 - globalPosFace12, nu6L1);
449 R_.mv(globalPosCenter - globalPos1, nu7L1);
453 R_.mv(nu2L1, Rnu2L1);
454 Scalar T1L1 = nu1L1 * Rnu2L1;
457 R_.mv(nu4L1, Rnu4L1);
458 Scalar T2L1 = nu3L1 * Rnu4L1;
461 R_.mv(nu6L1, Rnu6L1);
462 Scalar T3L1 = nu5L1 * Rnu6L1;
465 DimVector K1nu1L1(0);
466 K1.mv(nu1L1, K1nu1L1);
467 DimVector K1nu2L1(0);
468 K1.mv(nu2L1, K1nu2L1);
469 DimVector K3nu3L1(0);
470 K3.mv(nu3L1, K3nu3L1);
471 DimVector K3nu4L1(0);
472 K3.mv(nu4L1, K3nu4L1);
473 DimVector K2nu5L1(0);
474 K2.mv(nu5L1, K2nu5L1);
475 DimVector K2nu6L1(0);
476 K2.mv(nu6L1, K2nu6L1);
479 R_.mv(nu1L1, Rnu1L1);
481 DimVector &outerNormaln1L1 = interactionVolume.
getNormal(idx1, 1);
483 Scalar omega111L1 = lambda[idx1][1] * (outerNormaln1L1 * K1nu1L1) * interactionVolume.
getFaceArea(idx1, 1) / T1L1;
484 Scalar omega112L1 = lambda[idx1][1] * (outerNormaln1L1 * K1nu2L1) * interactionVolume.
getFaceArea(idx1, 1) / T1L1;
485 Scalar omega211L1 = lambda[idx1][0] * (outerNormaln2 * K1nu1L1) * interactionVolume.
getFaceArea(idx1, 0) / T1L1;
486 Scalar omega212L1 = lambda[idx1][0] * (outerNormaln2 * K1nu2L1) * interactionVolume.
getFaceArea(idx1, 0) / T1L1;
487 Scalar omega123L1 = lambda[idx3][0] * (outerNormaln1L1 * K3nu3L1) * interactionVolume.
getFaceArea(idx3, 0) / T2L1;
488 Scalar omega124L1 = lambda[idx3][0] * (outerNormaln1L1 * K3nu4L1) * interactionVolume.
getFaceArea(idx3, 0) / T2L1;
489 Scalar omega235L1 = lambda[idx2][1] * (outerNormaln2 * K2nu5L1) * interactionVolume.
getFaceArea(idx2, 1) / T3L1;
490 Scalar omega236L1 = lambda[idx2][1] * (outerNormaln2 * K2nu6L1) * interactionVolume.
getFaceArea(idx2, 1) / T3L1;
491 Scalar chi711L1 = (nu7L1 * Rnu1L1) / T1L1;
492 Scalar chi712L1 = (nu7L1 * Rnu2L1) / T1L1;
496 C[0][0] = -omega111L1;
497 C[0][1] = -omega112L1;
498 C[1][0] = -omega211L1;
499 C[1][1] = -omega212L1;
501 D[0][0] = omega111L1 + omega112L1;
502 D[1][0] = omega211L1 + omega212L1;
504 A[0][0] = omega111L1 - omega124L1 - omega123L1 * chi711L1;
505 A[0][1] = omega112L1 - omega123L1 * chi712L1;
506 A[1][0] = omega211L1 - omega236L1 * chi711L1;
507 A[1][1] = omega212L1 - omega235L1 - omega236L1 * chi712L1;
509 B[0][0] = omega111L1 + omega112L1 + omega123L1 * (1.0 - chi711L1 - chi712L1);
510 B[0][1] = -omega123L1 - omega124L1;
511 B[1][0] = omega211L1 + omega212L1 + omega236L1 * (1.0 - chi711L1 - chi712L1);
512 B[1][2] = -omega235L1 - omega236L1;
516 D += B.leftmultiply(C.rightmultiply(A));
519 transmissibilityLeft = D;
537template<
class TypeTag>
541 std::vector<DimVector >& lambda,
542 int idx1,
int idx2,
int idx3)
548 if (element2.level() != element3.level())
550 return noTransmissibility;
554 const GlobalPosition& globalPos1 = element1.geometry().center();
555 const GlobalPosition& globalPos2 = element2.geometry().center();
556 const GlobalPosition& globalPos3 = element3.geometry().center();
560 const DimMatrix& K1 = problem_.spatialParams().intrinsicPermeability(element1);
561 const DimMatrix& K2 = problem_.spatialParams().intrinsicPermeability(element2);
562 const DimMatrix& K3 = problem_.spatialParams().intrinsicPermeability(element3);
564 const GlobalPosition& globalPosFace12 = interactionVolume.
getFacePosition(idx1, 0);
565 const GlobalPosition& globalPosFace23 = interactionVolume.
getFacePosition(idx2, 0);
569 R_.mv(globalPosFace12 - globalPos2, nu1R1);
572 R_.mv(globalPos2 - globalPosFace23, nu2R1);
575 R_.mv(globalPosFace23 - globalPos3, nu3R1);
578 R_.mv(globalPos3 - globalPosCenter, nu4R1);
581 R_.mv(globalPosCenter - globalPos1, nu5R1);
584 R_.mv(globalPos1 - globalPosFace12, nu6R1);
587 R_.mv(globalPosCenter - globalPos2, nu7R1);
591 R_.mv(nu2R1, Rnu2R1);
592 Scalar T1R1 = nu1R1 * Rnu2R1;
595 R_.mv(nu4R1, Rnu4R1);
596 Scalar T2R1 = nu3R1 * Rnu4R1;
599 R_.mv(nu6R1, Rnu6R1);
600 Scalar T3R1 = nu5R1 * Rnu6R1;
603 DimVector K2nu1R1(0);
604 K2.mv(nu1R1, K2nu1R1);
605 DimVector K2nu2R1(0);
606 K2.mv(nu2R1, K2nu2R1);
607 DimVector K3nu3R1(0);
608 K3.mv(nu3R1, K3nu3R1);
609 DimVector K3nu4R1(0);
610 K3.mv(nu4R1, K3nu4R1);
611 DimVector K1nu5R1(0);
612 K1.mv(nu5R1, K1nu5R1);
613 DimVector K1nu6R1(0);
614 K1.mv(nu6R1, K1nu6R1);
617 R_.mv(nu1R1, Rnu1R1);
619 DimVector &outerNormaln1R1 = interactionVolume.
getNormal(idx2, 0);
620 DimVector &outerNormaln2 = interactionVolume.
getNormal(idx1, 0);
622 Scalar omega111R1 = lambda[idx2][0] * (outerNormaln1R1 * K2nu1R1) * interactionVolume.
getFaceArea(idx2, 0) / T1R1;
623 Scalar omega112R1 = lambda[idx2][0] * (outerNormaln1R1 * K2nu2R1) * interactionVolume.
getFaceArea(idx2, 0) / T1R1;
624 Scalar omega211R1 = lambda[idx2][1] * (outerNormaln2 * K2nu1R1) * interactionVolume.
getFaceArea(idx2, 1) / T1R1;
625 Scalar omega212R1 = lambda[idx2][1] * (outerNormaln2 * K2nu2R1) * interactionVolume.
getFaceArea(idx2, 1) / T1R1;
626 Scalar omega123R1 = lambda[idx3][1] * (outerNormaln1R1 * K3nu3R1) * interactionVolume.
getFaceArea(idx3, 1) / T2R1;
627 Scalar omega124R1 = lambda[idx3][1] * (outerNormaln1R1 * K3nu4R1) * interactionVolume.
getFaceArea(idx3, 1) / T2R1;
628 Scalar omega235R1 = lambda[idx1][0] * (outerNormaln2 * K1nu5R1) * interactionVolume.
getFaceArea(idx1, 0) / T3R1;
629 Scalar omega236R1 = lambda[idx1][0] * (outerNormaln2 * K1nu6R1) * interactionVolume.
getFaceArea(idx1, 0) / T3R1;
630 Scalar chi711R1 = (nu7R1 * Rnu1R1) / T1R1;
631 Scalar chi712R1 = (nu7R1 * Rnu2R1) / T1R1;
634 DimMatrix C(0), A(0);
638 C[0][0] = -omega111R1;
639 C[0][1] = -omega112R1;
640 C[1][0] = -omega211R1;
641 C[1][1] = -omega212R1;
643 D[0][0] = omega111R1 + omega112R1;
644 D[1][0] = omega211R1 + omega212R1;
646 A[0][0] = omega111R1 - omega124R1 - omega123R1 * chi711R1;
647 A[0][1] = omega112R1 - omega123R1 * chi712R1;
648 A[1][0] = omega211R1 - omega236R1 * chi711R1;
649 A[1][1] = omega212R1 - omega235R1 - omega236R1 * chi712R1;
651 B[0][0] = omega111R1 + omega112R1 + omega123R1 * (1.0 - chi711R1 - chi712R1);
652 B[0][1] = -omega123R1 - omega124R1;
653 B[1][0] = omega211R1 + omega212R1 + omega236R1 * (1.0 - chi711R1 - chi712R1);
654 B[1][2] = -omega235R1 - omega236R1;
658 D += B.leftmultiply(C.rightmultiply(A));
660 transmissibilityRight = D;
661 return rightTriangle;
Class including the information of an interaction volume of a MPFA L-method that does not change with...
int calculateTransmissibility(TransmissibilityType &transmissibility, InteractionVolume &interactionVolume, std::vector< DimVector > &lambda, int idx1, int idx2, int idx3, int idx4)
Calculates tranmissibility matrix.
Definition: 2dtransmissibilitycalculator.hh:136
int calculateRightHNTransmissibility(TransmissibilityType &transmissibility, InteractionVolume &interactionVolume, std::vector< DimVector > &lambda, int idx1, int idx2, int idx3)
Calculates tranmissibility matrix of right L-shape.
Definition: 2dtransmissibilitycalculator.hh:538
int calculateLeftHNTransmissibility(TransmissibilityType &transmissibility, InteractionVolume &interactionVolume, std::vector< DimVector > &lambda, int idx1, int idx2, int idx3)
Calculates tranmissibility matrix of left L-shape.
Definition: 2dtransmissibilitycalculator.hh:393
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:149
Provides methods for transmissibility calculation in 2-d.
Definition: 2dtransmissibilitycalculator.hh:44
FvMpfaL2dTransmissibilityCalculator(Problem &problem)
Constructs a FvMpfaL2dTransmissibilityCalculator object.
Definition: 2dtransmissibilitycalculator.hh:99
Dune::FieldMatrix< Scalar, dim, 2 *dim - dim+1 > TransmissibilityType
Type of the transmissibility matrix.
Definition: 2dtransmissibilitycalculator.hh:65
@ leftTriangle
Left L-shape.
Definition: 2dtransmissibilitycalculator.hh:70
@ rightTriangle
Right L-shape.
Definition: 2dtransmissibilitycalculator.hh:72
@ noTransmissibility
No transmissibility calculated.
Definition: 2dtransmissibilitycalculator.hh:71
Class including the information of an interaction volume of a MPFA L-method that does not change with...
Definition: linteractionvolume.hh:41
DimVector & getNormal(int subVolumeIdx, int subVolumeFaceIdxInInside)
Get a flux face normal.
Definition: linteractionvolume.hh:364
Element getSubVolumeElement(int subVolumeIdx)
Get an element of the interaction volume.
Definition: linteractionvolume.hh:281
DimVector & getFacePosition(int subVolumeIdx, int subVolumeFaceIdxInInside)
Get position of the center of a flux face.
Definition: linteractionvolume.hh:376
Scalar & getFaceArea(int subVolumeIdx, int subVolumeFaceIdxInInside)
Get a flux face area.
Definition: linteractionvolume.hh:388
DimVector & getCenterPosition()
Get position vector of central vertex.
Definition: linteractionvolume.hh:240
Properties for a MPFA method.
Base file for properties related to sequential IMPET algorithms.