167 {
168 TRACE();
169
171
173
174 MFloat currCollTime = 0.0, outtime;
175 MInt subIndex[3] = {numeric_limits<MInt>::max(), numeric_limits<MInt>::max(), numeric_limits<MInt>::max()};
176
178 MInt factor[MAX_SPACE_DIMENSIONS] = {numeric_limits<MInt>::max(), numeric_limits<MInt>::max(),
179 numeric_limits<MInt>::max()};
181
182
183
184
185 factor[0] = 1;
188
189
191 for(i1 = partList.begin(); i1 != partList.end(); i1++) {
192
193 if(!(*i1).toBeDeleted()) {
195 index2 = 0;
197 for(
MInt i = 0; i < nDim; i++) {
200 {
201 error = true;
202 break;
203 } else {
204 index += factor[i] * index2;
205 }
206 }
207
208 if(error) {
209 if(!(*i1).isInvalid()) {
210 stringstream errorMessage;
212 << (*i1).m_partId << " is lost!"
213 << " coord " << (*i1).m_position[0] << " " << (*i1).m_position[1] << " " << (*i1).m_position[2]
214 << " oldcoord " << (*i1).m_oldPos[0] << " " << (*i1).m_oldPos[1] << " " << (*i1).m_oldPos[2]
215 <<
" cellId " << (*i1).m_cellId <<
" coords " <<
m_lpt->c_coordinate((*i1).m_cellId, 0) <<
" "
216 <<
m_lpt->c_coordinate((*i1).m_cellId, 1) <<
" " <<
m_lpt->c_coordinate((*i1).m_cellId, 2)
217 <<
" halfLength " <<
m_lpt->c_cellLengthAtLevel(
m_lpt->c_level((*i1).m_cellId) + 1) << endl;
218 m_log << errorMessage.str();
219 }
220 if(!(*i1).wasSend() && !(*i1).toBeDeleted()) {
221 (*i1).toBeDeleted() = true;
222 m_log <<
"particle was lost " << endl;
223 }
224 } else {
226 }
227 }
228 }
229
231
233 while(i2 != partListEllipsoid.end()) {
234
235 if(!(*i2).toBeDeleted()) {
238 for(
MInt i = 0; i < nDim; i++) {
241 error = true;
242 break;
243 } else {
244 index += factor[i] * index2;
245 }
246 }
247
248 if(error) {
249 if(!(*i2).isInvalid()) {
250 stringstream errorMessage;
252 << (*i2).m_partId << " is lost!"
253 << " coord " << (*i2).m_position[0] << " " << (*i2).m_position[1] << " " << (*i2).m_position[2]
254 <<
" cellId " << (*i1).m_cellId <<
" coords " <<
m_lpt->c_coordinate((*i2).m_cellId, 0) <<
" "
255 <<
m_lpt->c_coordinate((*i2).m_cellId, 1) <<
" " <<
m_lpt->c_coordinate((*i2).m_cellId, 2)
256 <<
" halfLength " <<
m_lpt->c_cellLengthAtLevel(
m_lpt->c_level((*i2).m_cellId) + 1) << endl;
257 m_log << errorMessage.str();
258 }
259 if(!(*i2).toBeDeleted() && !(*i2).wasSend()) {
260 (*i2).toBeDeleted() = true;
261 (*i2).toBeRespawn() = true;
262 (*i2).isInvalid() = true;
263 m_log <<
"particle was lost " << endl;
264 }
265 } else {
267 }
268 }
269 i2++;
270 }
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285
291
292 for(
MInt j = 0; j < (
MInt)currDomain.subDomain.size(); j++) {
293
294
295 for(
MInt l = j + 1; l < (
MInt)currDomain.subDomain.size(); l++) {
296 thisCollTime =
298 if(thisCollTime >= 0.0)
299 {
300
306 }
307 }
308
309
310
311
312
314
315
317 IF_CONSTEXPR(nDim == 3) {
319 continue;
320 }
321 }
327 currCollTime);
328 if(thisCollTime >= 0.0)
329 {
330
336 }
337 }
338 }
339 }
340
346 currCollTime);
347 if(thisCollTime >= 0.0)
348 {
349
355 }
356 }
357 }
358 IF_CONSTEXPR(nDim == 3) {
364 currCollTime);
365 if(thisCollTime >= 0.0)
366 {
367
373 }
374 }
375 }
376 }
377 IF_CONSTEXPR(nDim == 3) {
384 currCollTime);
385 if(thisCollTime >= 0.0)
386 {
387
393 }
394 }
395 }
396 }
397
399
400
401
402 for(
MInt k = subIndex[0] - 1; k < subIndex[0] + 2; k++) {
404 continue;
405 }
406 for(
MInt l = subIndex[1] - 1; l < subIndex[1] + 2; l++) {
408 continue;
409 }
410 for(
MInt m = subIndex[2] - 1; m < subIndex[2] + 2; m++) {
412 continue;
413 }
418 }
419 }
420 }
421 }
422 }
423 }
424 }
425
428 index2 = 0;
429
430
431
432
433
434
435
436
437
438
439
440
445
447
448
452 }
453
454
455
456
457
458
459 for(
MInt k = 1; k < 8; k++) {
460
461
463 IF_CONSTEXPR(nDim == 3) {
465 continue;
466 }
467 }
473 }
474 }
475 }
476
482 }
483 }
489 }
490 }
497 }
498 }
499 }
500 }
501 }
502
504
505
507
510
516
517 if(bndryId > -1)
518 {
519 if(!(*collPair[0]).toBeDeleted()) {
520 switch(
m_lpt->a_bndryCellId(bndryId)) {
521 case 1012:
522 case 1002: {
523
524 if(!(*collPair[0]).wasSend() && !(*collPair[0]).toBeDeleted()) {
525 m_log <<
"particle left domain through outlet boundary" << endl;
526 (*collPair[0]).toBeDeleted() = true;
527 (*collPair[0]).toBeRespawn() = true;
528 (*collPair[0]).isInvalid() = true;
529 }
530 break;
531 }
532
533 case 1021:
534 case 1001: {
535
536
538 if(l >= 0.0 && l <= 1.1) {
539
540 if(!(*collPair[0]).wasSend() && !(*collPair[0]).toBeDeleted()) {
541 m_log <<
"particle left domain through inlet boundary" << endl;
542 (*collPair[0]).toBeDeleted() = true;
543 (*collPair[0]).toBeRespawn() = true;
544 (*collPair[0]).isInvalid() = true;
545 }
546 }
547 break;
548 }
549
550 case 3002:
551 case 3003:
552 case 3803:
553 {
554
555
556
558 MFloat bndryBasis[MAX_SPACE_DIMENSIONS][MAX_SPACE_DIMENSIONS];
559 MFloat normN[MAX_SPACE_DIMENSIONS - 1];
560 MFloat reboundVel[MAX_SPACE_DIMENSIONS];
561 MFloat oldCoordinates[MAX_SPACE_DIMENSIONS] = {numeric_limits<MFloat>::max(), numeric_limits<MFloat>::max(),
562 numeric_limits<MFloat>::max()};
563 std::array<std::array<MFloat, MAX_SPACE_DIMENSIONS>, MAX_SPACE_DIMENSIONS> A;
564 std::array<MFloat, MAX_SPACE_DIMENSIONS>
b;
565 fill_n(A[0].data(), MAX_SPACE_DIMENSIONS * MAX_SPACE_DIMENSIONS, 0.0);
566 fill_n(
b.data(), MAX_SPACE_DIMENSIONS, 0.0);
567
568 MFloat lambda = outtime / timeStep;
569
570 for(
MInt i = 0; i < nDim; i++) {
571 oldCoordinates[i] =
572 (*collPair[0]).m_oldPos[i] + lambda * ((*collPair[0]).m_position[i] - (*collPair[0]).m_oldPos[i]);
573 normVel +=
POW2(
m_lpt->m_bndryCells->a[bndryId].m_srfcs[0]->m_normal[i]
574 * ((*collPair[0]).m_position[i] - (*collPair[0]).m_oldPos[i]) / timeStep);
575
576
577
578
579
580
581 }
582
583
584
585
586
587 for(
MInt i = 0; i < nDim - 1; i++) {
588 normN[i] = 0.0;
589 }
590
591 for(
MInt i = 0; i < nDim - 1; i++) {
592 for(
MInt j = 0; j < nDim; j++) {
593 normN[i] +=
POW2(
m_lpt->m_bndryCells->a[bndryId].m_srfcs[0]->m_planeCoordinates[i + 1][j]
594 -
m_lpt->m_bndryCells->a[bndryId].m_srfcs[0]->m_planeCoordinates[0][j]);
595 }
596 }
597
598 for(
MInt i = 0; i < nDim - 1; i++) {
599 normN[i] = sqrt(normN[i]);
600 }
601
602 for(
MInt i = 0; i < nDim; i++) {
603 bndryBasis[i][0] =
m_lpt->m_bndryCells->a[bndryId].m_srfcs[0]->m_normal[i];
604 for(
MInt j = 1; j < nDim; j++) {
605 bndryBasis[i][j] = (
m_lpt->m_bndryCells->a[bndryId].m_srfcs[0]->m_planeCoordinates[j][i]
606 -
m_lpt->m_bndryCells->a[bndryId].m_srfcs[0]->m_planeCoordinates[0][i])
607 / normN[j - 1];
608 }
609 }
610
611
612
613 for(
MInt i = 0; i < nDim; i++) {
614 A[0][i] =
m_lpt->m_bndryCells->a[bndryId].m_srfcs[0]->m_normal[i];
615 for(
MInt j = 1; j < nDim; j++) {
616 A[j][i] = (
m_lpt->m_bndryCells->a[bndryId].m_srfcs[0]->m_planeCoordinates[j][i]
617 -
m_lpt->m_bndryCells->a[bndryId].m_srfcs[0]->m_planeCoordinates[0][i])
618 / normN[j - 1];
619 }
620 b[i] = (*collPair[0]).m_oldVel[i];
621 }
622
624
625
626
627
628 (*collPair[0]).m_oldVel[0] = 0.0;
629 reboundVel[0] = -
b[0];
630
631 for(
MInt i = 1; i < nDim; i++) {
632 (*collPair[0]).m_oldVel[i] = 0.0;
633 (*collPair[0]).m_velocity[i] = 0.0;
634 reboundVel[i] =
b[i];
635 }
636
637
638
639 for(
MInt i = 0; i < nDim; i++) {
640 for(
MInt j = 0; j < nDim; j++) {
641 (*collPair[0]).m_oldVel[i] += bndryBasis[i][j] * reboundVel[j];
642 (*collPair[0]).m_velocity[i] = (*collPair[0]).m_oldVel[i];
643 }
644 (*collPair[0]).m_position[i] = oldCoordinates[i] + (1.0 - lambda) * timeStep * (*collPair[0]).m_oldVel[i];
645 }
646
647 (*collPair[0]).checkCellChange(&(*collPair[0]).m_oldPos[0]);
648
649
650 for(
MInt i = 0; i < nDim; i++) {
651 (*collPair[0]).m_oldPos[i] = oldCoordinates[i] + (lambda - 1.0) * timeStep * (*collPair[0]).m_oldVel[i];
652 }
653
654 (*collPair[0]).hasCollided() = true;
655 (*collPair[0]).firstStep() = true;
656
657
658
659
660
661
662
663
664
665
666 break;
667 }
668 default: {
669
670 cerr << "WARNING: This boundary condition not implemented for particles!" << endl;
671 cerr << "Treated as a solid wall" << endl;
672 }
673 }
674 }
675
676
677
679
680
681
682 if(!(*collPair[0]).toBeDeleted()) {
683 MInt subCollIndex[3] = {numeric_limits<MInt>::max(), numeric_limits<MInt>::max(),
684 numeric_limits<MInt>::max()};
686 for(
MInt i = 0; i < nDim; i++) {
688 }
689
690 IF_CONSTEXPR(nDim == 2) {
691
692
693
694
695 for(
MInt i = (subCollIndex[0] - 1); i < (subCollIndex[0] + 2); i++) {
696 for(
MInt j = (subCollIndex[1] - 1); j < (subCollIndex[1] + 2); j++) {
704 if(_thisCollTime >= 0.0)
705 {
706
712 }
713 }
714 }
715 }
716 }
717 }
718 }
719 else {
720
721
722
723
724
725 for(
MInt i = (subCollIndex[0] - 1); i < (subCollIndex[0] + 2); i++) {
726 for(
MInt j = (subCollIndex[1] - 1); j < (subCollIndex[1] + 2); j++) {
727 for(
MInt k = (subCollIndex[2] - 1); k < (subCollIndex[2] + 2); k++) {
736 if(__thisCollTime >= 0.0)
737 {
738
744 }
745 }
746 }
747 }
748 }
749 }
750 }
751 }
752
753
755 }
756
757 currCollTime = outtime;
758
759 } else {
760 MFloat wdotr = 0.0, relVel = 0.0, meanVel = 0.0, deltap = 0.0;
761 MFloat vi0[MAX_SPACE_DIMENSIONS] = {numeric_limits<MFloat>::max(), numeric_limits<MFloat>::max(),
762 numeric_limits<MFloat>::max()};
763 MFloat vi1[MAX_SPACE_DIMENSIONS] = {numeric_limits<MFloat>::max(), numeric_limits<MFloat>::max(),
764 numeric_limits<MFloat>::max()};
765 MFloat r[MAX_SPACE_DIMENSIONS] = {numeric_limits<MFloat>::max(), numeric_limits<MFloat>::max(),
766 numeric_limits<MFloat>::max()};
767 MFloat x0old[MAX_SPACE_DIMENSIONS] = {numeric_limits<MFloat>::max(), numeric_limits<MFloat>::max(),
768 numeric_limits<MFloat>::max()};
769 MFloat x1old[MAX_SPACE_DIMENSIONS] = {numeric_limits<MFloat>::max(), numeric_limits<MFloat>::max(),
770 numeric_limits<MFloat>::max()};
771 MFloat partMass0, partMass1;
772 MFloat pointOfImpact[MAX_SPACE_DIMENSIONS] = {numeric_limits<MFloat>::max(), numeric_limits<MFloat>::max(),
773 numeric_limits<MFloat>::max()};
774 MFloat rLength = (*collPair[1]).m_diameter / ((*collPair[0]).m_diameter + (*collPair[1]).m_diameter);
776
777
778
779
780
781
782
783 MBool writeThisColl =
true;
784 MBool haloPart0 = (*collPair[0]).wasSend();
785 MBool haloPart1 = (*collPair[1]).wasSend();
786 MBool larger = ((*collPair[0]).m_partId > (*collPair[1]).m_partId);
787 if(haloPart0 & haloPart1) {
788 writeThisColl = false;
789 }
790 if(haloPart0 ^ haloPart1) {
791 if(haloPart1 & larger) {
792 writeThisColl = false;
793 }
794 if(haloPart0 & !larger) {
795 writeThisColl = false;
796 }
797 }
798
799
800
801 for(
MInt k = 0; k < nDim; k++) {
802 vi0[k] = ((*collPair[0]).m_position[k] - (*collPair[0]).m_oldPos[k]) / timeStep;
803 vi1[k] = ((*collPair[1]).m_position[k] - (*collPair[1]).m_oldPos[k]) / timeStep;
804 r[k] = ((*collPair[0]).m_oldPos[k] + outtime * vi0[k]) - ((*collPair[1]).m_oldPos[k] + outtime * vi1[k]);
805 x0old[k] = (*collPair[0]).m_oldPos[k];
806 x1old[k] = (*collPair[1]).m_oldPos[k];
807 wdotr += r[k] * (vi0[k] - vi1[k]);
808 relVel +=
POW2(vi0[k] - vi1[k]);
809 meanVel +=
POW2(vi0[k] + vi1[k]);
810
811 pointOfImpact[k] = (*collPair[1]).m_oldPos[k] + outtime * vi1[k] + r[k] * rLength;
812 }
813
814
815
816
817 relVel = sqrt(relVel);
818 meanVel = 0.5 * sqrt(meanVel);
819
820 partMass0 = F1B6 * PI * (*collPair[0]).m_densityRatio *
POW3((*collPair[0]).m_diameter);
821 partMass1 = F1B6 * PI * (*collPair[1]).m_densityRatio *
POW3((*collPair[1]).m_diameter);
822
824
825 qmax = 2;
826 for(
MInt k = 0; k < nDim; k++) {
827 deltap = -2.0 * wdotr * r[k]
828 / ((partMass0 + partMass1) * 0.25 *
POW2((*collPair[0]).m_diameter + (*collPair[1]).m_diameter));
829 (*collPair[0]).m_velocity[k] = vi0[k] + deltap * partMass1;
830 (*collPair[1]).m_velocity[k] = vi1[k] - deltap * partMass0;
831 (*collPair[0]).m_position[k] =
832 (*collPair[0]).m_oldPos[k] + vi0[k] * outtime + (*collPair[0]).m_velocity[k] * (timeStep - outtime);
833 (*collPair[1]).m_position[k] =
834 (*collPair[1]).m_oldPos[k] + vi1[k] * outtime + (*collPair[1]).m_velocity[k] * (timeStep - outtime);
835 }
836
837
838 (*collPair[0]).checkCellChange(x0old);
839 (*collPair[1]).checkCellChange(x1old);
840
841 for(
MInt k = 0; k < nDim; k++) {
842
843 (*collPair[0]).m_oldPos[k] = (*collPair[0]).m_position[k] - (*collPair[0]).m_velocity[k] * timeStep;
844 (*collPair[1]).m_oldPos[k] = (*collPair[1]).m_position[k] - (*collPair[1]).m_velocity[k] * timeStep;
845 }
846
847 (*collPair[0]).hasCollided() = true;
848 (*collPair[0]).firstStep() = true;
849 (*collPair[1]).hasCollided() = true;
850 (*collPair[1]).firstStep() = true;
851
854 for(
MInt k = 0; k < nDim; k++) {
855 part2CFL +=
POW2((*collPair[1]).m_velocity[k]);
856 }
857 part2CFL *=
POW2(timeStep / (*collPair[1]).m_diameter);
858 if(part2CFL > 0.04) {
859 cout << "Caution: a particle CFL number of " << sqrt(part2CFL) << " has been found!\n";
860 }
861 }
862
863
866 }
867
869
870
871 if((*collPair[0]).m_partId > (*collPair[1]).m_partId) {
872 qmax = (*collPair[0]).m_partId;
873 (*collPair[0]).m_partId = (*collPair[1]).m_partId;
874 (*collPair[1]).m_partId = qmax;
875 }
876 qmax = 1;
877
878
879 MFloat FSumMass = 1.0 / (partMass0 + partMass1);
880
881 for(
MInt k = 0; k < nDim; k++) {
882 (*collPair[0]).m_velocity[k] =
883 FSumMass * (partMass0 * (*collPair[0]).m_velocity[k] + partMass1 * (*collPair[1]).m_velocity[k]);
884 (*collPair[0]).m_oldVel[k] = (*collPair[1]).m_velocity[k];
885 (*collPair[0]).m_position[k] = FSumMass
886 * (partMass0 * ((*collPair[0]).m_oldPos[k] + outtime * vi0[k])
887 + partMass1 * ((*collPair[1]).m_oldPos[k] + outtime * vi1[k]))
888 + (timeStep - outtime) * (*collPair[0]).m_velocity[k];
889 }
890
891
892 (*collPair[0]).checkCellChange(x0old);
893
894 for(
MInt k = 0; k < nDim; k++) {
895 (*collPair[0]).m_oldPos[k] = (*collPair[0]).m_position[k] - timeStep * (*collPair[0]).m_velocity[k];
896 }
897
898 MFloat diam0 = (*collPair[0]).m_diameter;
899 MFloat diam1 = (*collPair[1]).m_diameter;
902 (*collPair[0]).m_diameter = pow(diam03 + diam13, F1B3);
903 (*collPair[0]).m_densityRatio =
904 (diam03 * (*collPair[0]).m_densityRatio + diam13 * (*collPair[1]).m_densityRatio) / (diam03 + diam13);
905
906
907
908 (*collPair[0]).hasCollided() = true;
909 (*collPair[0]).firstStep() = true;
910
911
914
915
916 (*collPair[1]).toBeDeleted() = true;
917 (*collPair[0]).isInvalid() = true;
918 }
919
921
922
925 for(
MInt k = 0; k < nDim; k++) {
926 part2CFL +=
POW2((*collPair[1]).m_velocity[k]);
927 }
928 part2CFL *=
POW2(timeStep / (*collPair[1]).m_diameter);
929 if(part2CFL > 0.04) {
930 cout << "Caution: a particle CFL number of " << sqrt(part2CFL) << " has been found!\n";
931 }
932 }
933
935 }
936
937
938
941 for(
MInt k = 0; k < nDim; k++) {
942 part0CFL +=
POW2((*collPair[0]).m_velocity[k]);
943 }
944 part0CFL *=
POW2(timeStep / (*collPair[0]).m_diameter);
945 if(part0CFL > 0.04) {
946 cout << "Caution: a particle CFL number of " << sqrt(part0CFL) << " has been found!\n";
947 }
948 }
949
950
951
952
953 currCollTime = outtime;
954
956
957
958 IF_CONSTEXPR(nDim == 2) {
959
960
961
962
963
964 for(
MInt q = 0; q < qmax; q++) {
965 if((*collPair[q]).toBeDeleted()) {
966 continue;
967 }
968 for(
MInt i = 0; i < nDim; i++) {
970 }
971
972 for(
MInt i = (subIndex[0] - 1); i < (subIndex[0] + 2); i++) {
973 for(
MInt j = (subIndex[1] - 1); j < (subIndex[1] + 2); j++) {
981 if(_thisCollTime >= 0.0)
982 {
983
989 }
990 }
991 }
992 }
993 }
994 }
995 }
996 }
997 else {
998
999
1000
1001
1002
1003
1004 for(
MInt q = 0; q < qmax; q++) {
1005 if((*collPair[q]).toBeDeleted()) {
1006 continue;
1007 }
1008 for(
MInt i = (subIndex[0] - 1); i < (subIndex[0] + 2); i++) {
1009 for(
MInt j = (subIndex[1] - 1); j < (subIndex[1] + 2); j++) {
1010 for(
MInt k = (subIndex[2] - 1); k < (subIndex[2] + 2); k++) {
1019 if(__thisCollTime >= 0.0)
1020 {
1021
1024 thisColl.
collTime = __thisCollTime;
1027 }
1028 }
1029 }
1030 }
1031 }
1032 }
1033 }
1034 }
1035 }
1036
1037 if(
m_lpt->m_wallCollisions) {
1038
1039 for(
MInt q = 0; q < qmax; q++) {
1040 if((*collPair[q]).toBeDeleted()) {
1041 continue;
1042 }
1044 }
1045 }
1046 }
1047
1048
1049 if(writeThisColl) {
1050
1051
1053 writeCollEvent(time, (*collPair[0]).m_partId, (*collPair[1]).m_partId, (*collPair[0]).m_diameter,
1054 (*collPair[1]).m_diameter, (*collPair[0]).m_densityRatio, (*collPair[1]).m_densityRatio,
1055 relVel, meanVel, pointOfImpact);
1056 }
1057 }
1058 }
1059 }
1060
1063 }
1064
1068 }
1069 }
1070}
maia::lpt::subDomainCollectorEllipsoid< nDim > * subDomainContentEllipsoid
MFloat checkBndryCross(MInt, lptParticleI, MFloat)
Checks crossing of boundary surface of the boundary cell.
void collisionCheckSphereEllipsoid(lptParticleI, lptEllipticleI)
Collision check for ellipsoids i2 and i3 calls the corresponding proactive or retroactive method.
void geometryInteraction()
MFloat collisionCheck(lptParticleI, lptParticleI, MFloat)
Checks whether particles i and j collide after currCollTime, and returns collision time.
MFloat m_subDomainSize[3]
maia::lpt::subDomainCollector< nDim > * subDomainContent
void collisionCheckEllipsoidEllipsoid(lptEllipticleI, lptEllipticleI)
Collision check for ellipsoids i2 and i3 calls the corresponding proactive or retroactive method.
std::list< collStruct< nDim > > collList
void writeCollEvent(MFloat collisionTime, MInt particle0, MInt particle1, MFloat diam0, MFloat diam1, MFloat dens0, MFloat dens1, MFloat relVel, MFloat meanVel, MFloat *x)
Add collision data to queue which is to be written.
MFloat m_subDomainCoordOffset[3]
MBool m_includeEllipsoids
std::vector< LPTSpherical< nDim > >::iterator particle1
std::vector< LPTSpherical< nDim > >::iterator particle0
constexpr Real POW3(const Real x)
constexpr MLong IPOW2(MInt x)
IdType index(const FloatType *const x, const IdType level)
Return Hilbert index for given location and level in 2D or 3D.
typename std::vector< LPTSpherical< nDim > >::iterator partListIterator
typename std::vector< LPTEllipsoidal< nDim > >::iterator ellipsListIterator
template void solveQR< 3 >(std::array< std::array< MFloat, 3 >, 3 > &, std::array< MFloat, 3 > &)