@@ -860,29 +860,44 @@ void MPMesh::solveMatrix(const Kokkos::View<double**>& vtxMatrices, double& radi
860860void MPMesh::invertMatrix (const Kokkos::View<double **>& vtxMatrices, const double & radius){
861861
862862 static int count_deb = 1 ;
863- std::cout<<__FUNCTION__<<count_deb<<std::endl;
863+ std::cout<<__FUNCTION__<<count_deb<<" ========================= " << std::endl;
864864
865865 int nVertices = p_mesh->getNumVertices ();
866866 auto vtxCoords = p_mesh->getMeshField <polyMPO::MeshF_VtxCoords>();
867867 auto dual_triangle_area = p_mesh->getMeshField <MeshF_DualTriangleArea>();
868868 bool isRotated=false ;
869869
870- Kokkos::View<double *[3 ][vec4d_nEntries]> VtxCoeffs (" VtxCoeffs" , nVertices);
870+ double eps = 1e-7 ;
871+ double truncateFactor = 0.05 ;
872+
873+ Kokkos::View<double *[3 ][vec4d_nEntries]> VtxCoeffs (" VtxCoeffs" , nVertices);
874+ Kokkos::deep_copy (VtxCoeffs, 0.0 );
875+
871876 Kokkos::parallel_for (" invertMatrix" , nVertices, KOKKOS_LAMBDA (const int vtx){
872- auto relativeScale = vtxMatrices (vtx, 0 )*dual_triangle_area (vtx, 0 )/(radius*radius);
877+ if (vtxMatrices (vtx, 0 ) < eps)
878+ return ;
879+
880+ auto small = eps * vtxMatrices (vtx, 0 ) * dual_triangle_area (vtx, 0 )/(radius*radius);
881+ auto truncate = truncateFactor * vtxMatrices (vtx, 0 ) * dual_triangle_area (vtx, 0 )/(radius*radius);
882+
883+ double X = vtxCoords (vtx, 0 )/radius;
884+ double Y = vtxCoords (vtx, 1 )/radius;
885+ double Z = vtxCoords (vtx, 2 )/radius;
873886 if (isRotated){
874-
887+ // Change X and Z
875888 }
876- auto cosLat = sqrt (pow (vtxCoords (vtx,0 )/radius, 2 ) + pow (vtxCoords (vtx,1 )/radius, 2 ));
889+
890+ auto cosLat = sqrt (pow (X, 2 ) + pow (Y, 2 ));
891+ auto invCosLat = 1.0 /cosLat;
877892 auto vtx_area_sqrt = sqrt (dual_triangle_area (vtx,0 )/(radius*radius));
878- Vec3d v0 = { -vtxCoords (vtx, 1 )/(radius*cosLat), -vtxCoords (vtx, 2 )*vtxCoords (vtx, 0 )/(radius*radius*cosLat), vtxCoords (vtx, 0 )/(radius*vtx_area_sqrt) };
879- Vec3d v1 = { vtxCoords (vtx, 0 )/(radius*cosLat), -vtxCoords (vtx, 1 )*vtxCoords (vtx, 2 )/(radius*radius*cosLat), vtxCoords (vtx, 1 )/(radius*vtx_area_sqrt) };
880- Vec3d v2 = { 0 , cosLat, vtxCoords (vtx, 2 )/(radius*vtx_area_sqrt) };
881893
882- Matrix3d rotateScaleM = {v0, v1, v2};
894+ Vec3d v0 = { -Y * invCosLat, -Z * X * invCosLat, X / vtx_area_sqrt };
895+ Vec3d v1 = { X * invCosLat, -Y * Z * invCosLat, Y / vtx_area_sqrt };
896+ Vec3d v2 = { 0.0 , cosLat, Z /vtx_area_sqrt };
883897 if (isRotated){
884898
885899 }
900+ Matrix3d rotateScaleM = {v0, v1, v2};
886901
887902 double invM11 = 1.0 / vtxMatrices (vtx, 0 );
888903 Matrix3d subM;
@@ -897,24 +912,37 @@ void MPMesh::invertMatrix(const Kokkos::View<double**>& vtxMatrices, const doubl
897912 subM (2 , 1 ) = subM (1 , 2 );
898913
899914 auto subM1 = (rotateScaleM.transpose ())*(subM*rotateScaleM);
900-
901- auto trG = subM1 (0 , 0 ) + subM1 (1 , 1 );
902- if ((trG < 1e-4 * relativeScale) || (vtxMatrices (vtx, 0 )<0.01 )){
903- VtxCoeffs (vtx, 0 , 0 ) = invM11;
904- return ;
905- }
906-
915+
907916 Vec3d mVec = {vtxMatrices (vtx, 1 ), vtxMatrices (vtx, 2 ), vtxMatrices (vtx, 3 )};
908917 auto blockC = rotateScaleM * mVec ;
909918
910- auto delG = sqrt (4.0 * pow (subM1 (0 , 1 ), 2 ) + pow ( subM1 (0 , 0 )-subM1 (1 , 1 ), 2 ));
911- auto minEig = 0.5 * (trG-delG);
912- double regularization = max (0.1 * relativeScale - minEig, 0.0 );
913- subM1 (0 , 0 ) = subM1 (0 , 0 ) + regularization;
914- subM1 (1 , 1 ) = subM1 (1 , 1 ) + regularization;
919+ auto trG = subM1 (0 , 0 ) + subM1 (1 , 1 );
920+ if ((trG < small) || (vtxMatrices (vtx, 0 ) < truncateFactor)){
921+ VtxCoeffs (vtx, 0 , 0 ) = invM11;
922+ return ;
923+ }
924+
925+ auto diffTr = subM1 (0 , 0 )-subM1 (1 , 1 );
926+ auto delG = sqrt (4.0 * pow (subM1 (0 , 1 ), 2 ) + pow (diffTr, 2 ));
927+ if (delG<small){
928+ subM1 (0 , 0 ) = max (subM1 (0 , 0 ), truncate);
929+ subM1 (1 , 1 ) = max (subM1 (1 , 1 ), truncate);
930+ subM1 (0 , 1 ) = 0.0 ;
931+ }
932+ else {
933+ auto minEig = max (0.5 * (trG - delG), truncate);
934+ auto maxEig = max (0.5 * (trG + delG), truncate);
935+ auto trG = minEig + maxEig;
936+ auto diffEig = maxEig - minEig;
937+ diffTr = diffTr / delG;
938+ subM1 (0 , 0 ) = 0.5 * (trG + diffTr * diffEig);
939+ subM1 (1 , 1 ) = 0.5 * (trG - diffTr * diffEig);
940+ subM1 (0 , 1 ) = (1.0 / delG) * subM1 (0 , 1 ) * diffEig;
941+ }
915942
916- double minZ2 = max (pow (subM1 (0 , 2 ), 2 )/subM1 (0 , 0 ), pow (subM1 (1 , 2 ), 2 )/subM1 (1 , 1 )) + 0.1 * minEig;
917- subM1 (2 , 2 ) = max (subM1 (2 , 2 ), minZ2);
943+ double denom = subM1 (0 , 0 ) * subM1 (1 , 1 ) - pow (subM1 (0 , 1 ), 2 ) ;
944+ double minZ2 = (subM1 (1 , 1 ) * pow (subM1 (0 , 2 ), 2 ) + subM1 (0 , 0 ) * pow (subM1 (1 , 2 ), 2 ) - 2.0 * subM1 (0 , 1 ) * subM1 (0 , 2 ) * subM1 (1 , 2 ))/denom;
945+ subM1 (2 , 2 ) = max (subM1 (2 , 2 ), abs (minZ2) + truncate);
918946
919947 double invM2D[6 ]={0.0 };
920948 invM2D[0 ] = subM1 (2 , 2 ) * subM1 (1 , 1 ) - subM1 (1 , 2 ) * subM1 (1 , 2 );
@@ -939,7 +967,7 @@ void MPMesh::invertMatrix(const Kokkos::View<double**>& vtxMatrices, const doubl
939967 VtxCoeffs (vtx, 0 , 3 ) = temp[2 ];
940968
941969 // Debugging
942- if (vtx == 315459 ){
970+ if (vtx == 33821 ){
943971 printf (" Matrices %d vtx \n " , vtx);
944972 printf (" [ %.15e %.15e %.15e %.15e ]\n " , vtxMatrices (vtx,0 ), vtxMatrices (vtx,1 ), vtxMatrices (vtx,2 ), vtxMatrices (vtx,3 ));
945973 printf (" [ %.15e %.15e %.15e %.15e ]\n " , vtxMatrices (vtx,1 ), vtxMatrices (vtx,4 ), vtxMatrices (vtx,5 ), vtxMatrices (vtx,6 ));
@@ -948,6 +976,14 @@ void MPMesh::invertMatrix(const Kokkos::View<double**>& vtxMatrices, const doubl
948976 printf (" Coefficients %d vtx \n " , vtx);
949977 for (int i=0 ; i<4 ; i++) printf (" %.15e " , VtxCoeffs (vtx, 0 , i));
950978 printf (" \n " );
979+ printf (" %.15e \n " , invM11);
980+ for (int i=0 ; i<3 ; i++) printf (" %.15e " , iBlockC[i]);
981+ printf (" \n " );
982+ for (int i=0 ; i<3 ; i++) printf (" %.15e " , blockC[i]);
983+ printf (" \n " );
984+ for (int i=0 ; i<6 ; i++) printf (" %.15e " , invM2D[i]);
985+ printf (" \n " );
986+ printf (" %.15e \n " , minZ2);
951987 }
952988 });
953989 this ->precomputedVtxCoeffs_new = VtxCoeffs;
@@ -1025,7 +1061,7 @@ void MPMesh::reconstruct_full() {
10251061
10261062 // Debug Delete
10271063 Kokkos::parallel_for (" printSymmetricBlock" , numVertices, KOKKOS_LAMBDA (const int vtx){
1028- if (vtx ==315459 ) {
1064+ if (vtx == 33821 ) {
10291065 printf (" IceArea in %d: " , vtx);
10301066 printf (" %25.15e \n " , meshField (vtx, 0 ));
10311067 }
0 commit comments