void TensorInverse(const Tensor<DataMesh>& t, Tensor<DataMesh>& inv) { ASSERT(t.Rank() == 2, "Not a matrix"); ASSERT(t.Dim() == 3, "Not 3D"); ASSERT(t.Structure() == inv.Structure(), "Tensors have different structures"); DataMesh det = t(0,0); TensorDeterminant(t, det); for(int i=0;i<det.Size();i++) { ASSERT(det[i] != 0, "Singular matrix"); } for(TensorIter it(t);it;++it) { IPoint ind = t.Structure().Indices(it.Index()); inv[it] = (t((ind[1]+1)%3,(ind[0]+1)%3) * t((ind[1]+2)%3,(ind[0]+2)%3) - t((ind[1]+1)%3,(ind[0]+2)%3) * t((ind[1]+2)%3,(ind[0]+1)%3)) / det; } }
Tensor<DataMesh> findInverse(const Tensor<DataMesh>& T){ /** Compute the inverse of the given Tensor using a minor expansion. */ const Mesh m(T(0).Extents()); DataMesh det = computeDet(T); for(int k=0;k<det.Size();k++){ REQUIRE(det[k]>1e-15 || det[k]<1e-15,"determinant is too close to zero!\n"); } //The inverse of a symmetric matrix is symmetric: Tensor<DataMesh> inverse(3,"aa",m,0.0); inverse(0,0) = (T(1,1)*T(2,2)-T(1,2)*T(2,1))/det; inverse(0,1) = -(T(1,0)*T(2,2)-T(1,2)*T(2,0))/det; inverse(0,2) = (T(1,0)*T(2,1)-T(1,1)*T(2,0))/det; inverse(1,1) = (T(0,0)*T(2,2)-T(0,2)*T(2,0))/det; inverse(1,2) = -(T(0,0)*T(2,1)-T(0,1)*T(2,0))/det; inverse(2,2) = (T(0,0)*T(1,1)-T(0,1)*T(1,0))/det; return inverse; }
int main(int /*argc*/, char** /*argv*/) { //create Strahlkorper, SurfaceBasis, SurfaceBasisExt objects int l=4; //int m=2*l+1; StrahlkorperMesh skm(l+1, 2*(l+1)); //print l,m std::cout << "(l,m) should be ("<<l<<","<<l<<"); M->2M+1" << std::endl; std::cout << "(l,m) = (" << skm.Basis().L() << "," << skm.Basis().M() << ")"<< std::endl; SurfaceBasis sb(skm); SurfaceBasisExt sbe(skm); //copy surface coords into individual DataMeshes DataMesh theta = skm.SurfaceCoords()(0); DataMesh phi = skm.SurfaceCoords()(1); //check theta, phi Dim std::cout << "theta.Dim() = " << theta.Dim() << std::endl; std::cout << "phi.Dim() = " << phi.Dim() << std::endl; //check theta, phi extents std::cout << "theta.Extents() = " << theta.Extents() << std::endl; std::cout << "phi.Extents() = " << phi.Extents() << std::endl; //initialize result, solution, and difference DataMeshes DataMesh resultDm(theta); DataMesh solutionDm(theta); DataMesh differenceDm(theta); DataMesh coefficientMeshDm(sbe.CoefficientMesh()); std::cout << "CoefficientMeshDm dimension is " << coefficientMeshDm.Dim() << std::endl; //check resultDm Dim, Extents std::cout << "resultDm.Dim() = " << resultDm.Dim() << std::endl; std::cout << "resultDm.Extents() = " << resultDm.Extents() << std::endl; //initialize result, solution, and difference Tensor<DataMesh>-es Tensor<DataMesh> operandTDm(skm.SurfaceCoords()); Tensor<DataMesh> resultTDm(skm.SurfaceCoords()); Tensor<DataMesh> solutionTDm(skm.SurfaceCoords()); Tensor<DataMesh> differenceTDm(skm.SurfaceCoords()); //check resultTDm Rank, Dim std::cout << "resultTDm.Rank() = " << resultTDm.Rank() << std::endl; std::cout << "resultTDm.Dim() = " << resultTDm.Dim() << std::endl; std::cout << "\n" << std::endl; std::cout << "Test results for various functions. The printed results \n" "show the L1Norm for the difference between the numerical \n" "result and analytical solution. A successful test will \n" "print out 0. \n" << std::endl; //test VectorPhysToSpec function in SurfaceBasisExt std::cout << "VectorPhysToSpec w/ SurfaceBasisExt, \n" "f(theta,phi)=-sin(theta) thetaHat + sin(theta) phiHat\n" << std::endl; operandTDm(0)=-sin(theta); operandTDm(1)=sin(theta); resultTDm(0)=0.0; resultTDm(1)=0.0; sbe.VectorPhysToSpec(operandTDm(0).Data(), operandTDm(1).Data(), 1, resultTDm(0).Data(), resultTDm(1).Data(), 1 ); std::cout << "Result " << "\n" << resultTDm(0) << "\n " << resultTDm(1) << "\n " << std::endl; //test VectorInterpAtPoint function in SurfaceBasisExt std::cout << "VectorInterpAtPoint w/ SurfaceBasisExt, \n" "f(0,0) = (0,0) \n" << std::endl; MyVector<double> value1(MV::Size(2),0.0); MyVector<double> value2 = sbe.VectorInterpAtPoint(operandTDm, value1, 0.,0.); std::cout << "value1 " << value1 << "\n" << "value2 " << value2 << std::endl; std::cout << "VectorInterpAtPoint w/ SurfaceBasisExt, \n" "f(pi/2,pi/2) = (-1,1) \n" << std::endl; value2 = sbe.VectorInterpAtPoint(operandTDm, value1, M_PI/2., M_PI/2.); std::cout << "value1 " << value1 << "\n" << "value2 " << value2 << std::endl; std::cout << "VectorInterpAtPoint w/ SurfaceBasisExt, \n" "f(pi/4,pi/4) = (-sqrt(2)/2, sqrt(2)/2) \n" << std::endl; value2 = sbe.VectorInterpAtPoint(operandTDm, value1, M_PI/4., M_PI/4.); std::cout << "value1 " << value1 << "\n" << "value2 " << value2 << std::endl; /**/ //Return success //return u.NumberOfTestsFailed(); return EXIT_SUCCESS; }