Skip to content

Commit da48034

Browse files
committed
Matrix inversion, Chad's fork
1 parent b45c37b commit da48034

File tree

1 file changed

+61
-25
lines changed

1 file changed

+61
-25
lines changed

src/pmpo_MPMesh_assembly.hpp

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -860,29 +860,44 @@ void MPMesh::solveMatrix(const Kokkos::View<double**>& vtxMatrices, double& radi
860860
void 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

Comments
 (0)