Example #1
0
// M_EigenValsProjsNum computes the eigenvalues and eigenprojectors of tensor 'a' (2nd order symmetric tensor in Mandel's basis)
// using Jacobi rotation.
func M_EigenValsProjsNum(P [][]float64, λ, a []float64) (err error) {
	Q := Alloc2()
	A := Alloc2()
	Man2Ten(A, a)
	_, err = la.Jacobi(Q, λ, A)
	if err != nil {
		return
	}
	P[0][0] = Q[0][0] * Q[0][0]
	P[0][1] = Q[1][0] * Q[1][0]
	P[0][2] = Q[2][0] * Q[2][0]
	P[0][3] = Q[0][0] * Q[1][0] * SQ2
	P[1][0] = Q[0][1] * Q[0][1]
	P[1][1] = Q[1][1] * Q[1][1]
	P[1][2] = Q[2][1] * Q[2][1]
	P[1][3] = Q[0][1] * Q[1][1] * SQ2
	P[2][0] = Q[0][2] * Q[0][2]
	P[2][1] = Q[1][2] * Q[1][2]
	P[2][2] = Q[2][2] * Q[2][2]
	P[2][3] = Q[0][2] * Q[1][2] * SQ2
	if len(a) == 6 {
		P[0][4] = Q[1][0] * Q[2][0] * SQ2
		P[0][5] = Q[2][0] * Q[0][0] * SQ2
		P[1][4] = Q[1][1] * Q[2][1] * SQ2
		P[1][5] = Q[2][1] * Q[0][1] * SQ2
		P[2][4] = Q[1][2] * Q[2][2] * SQ2
		P[2][5] = Q[2][2] * Q[0][2] * SQ2
	}
	return
}
Example #2
0
// M_EigenValsNum returns the eigenvalues of tensor 'a' (2nd order symmetric tensor in Mandel's basis)
// using Jacobi rotation
func M_EigenValsNum(λ, a []float64) (err error) {
	Q := Alloc2()
	A := Alloc2()
	Man2Ten(A, a)
	_, err = la.Jacobi(Q, λ, A)
	return
}
Example #3
0
// M_PrincValsNum returns the (sorted, ascending) eigenvalues of tensor 'a' (2nd order symmetric tensor in Mandel's basis)
// using Jacobi rotation.
func M_PrincValsNum(a []float64) (λ0, λ1, λ2 float64, err error) {
	Q := Alloc2()
	A := Alloc2()
	v := make([]float64, 3)
	Man2Ten(A, a)
	_, err = la.Jacobi(Q, v, A)
	if err != nil {
		return
	}
	λ0, λ1, λ2 = v[0], v[1], v[2]
	utl.DblSort3(&λ0, &λ1, &λ2)
	return
}
Example #4
0
// M_EigenValsVecs returns the eigenvalues and eigenvectors of tensor 'a' (2nd order symmetric tensor in Mandel's basis)
// using Jacobi rotation.
func M_EigenValsVecsNum(Q [][]float64, λ, a []float64) (err error) {
	A := Alloc2()
	Man2Ten(A, a)
	_, err = la.Jacobi(Q, λ, A)
	return
}
Example #5
0
// M_EigenProjsDerivNum returns the derivatives of the eigenprojectors w.r.t its defining tensor
// using the finite differences method.
//  Input:
//    a -- tensor in Mandel basis
//    h -- step size for finite differences
//  Output:
//    dPda -- derivatives [3][ncp][ncp]
func M_EigenProjsDerivNum(dPda [][][]float64, a []float64, h float64) (err error) {
	ncp := len(a)
	λ := make([]float64, 3)
	P := la.MatAlloc(3, ncp)
	Q := Alloc2()
	A := Alloc2()
	q2p := func(k int) {
		switch k {
		case 0:
			P[0][0] = Q[0][0] * Q[0][0]
			P[0][1] = Q[1][0] * Q[1][0]
			P[0][2] = Q[2][0] * Q[2][0]
			P[0][3] = Q[0][0] * Q[1][0] * SQ2
			if ncp == 6 {
				P[0][4] = Q[1][0] * Q[2][0] * SQ2
				P[0][5] = Q[2][0] * Q[0][0] * SQ2
			}
		case 1:
			P[1][0] = Q[0][1] * Q[0][1]
			P[1][1] = Q[1][1] * Q[1][1]
			P[1][2] = Q[2][1] * Q[2][1]
			P[1][3] = Q[0][1] * Q[1][1] * SQ2
			if ncp == 6 {
				P[1][4] = Q[1][1] * Q[2][1] * SQ2
				P[1][5] = Q[2][1] * Q[0][1] * SQ2
			}
		case 2:
			P[2][0] = Q[0][2] * Q[0][2]
			P[2][1] = Q[1][2] * Q[1][2]
			P[2][2] = Q[2][2] * Q[2][2]
			P[2][3] = Q[0][2] * Q[1][2] * SQ2
			if ncp == 6 {
				P[2][4] = Q[1][2] * Q[2][2] * SQ2
				P[2][5] = Q[2][2] * Q[0][2] * SQ2
			}
		}
	}
	var tmp float64
	failed := false
	for k := 0; k < 3; k++ {
		for i := 0; i < ncp; i++ {
			for j := 0; j < ncp; j++ {
				dPda[k][i][j], _ = num.DerivCentral(func(x float64, args ...interface{}) float64 {
					tmp, a[j] = a[j], x
					defer func() { a[j] = tmp }()
					Man2Ten(A, a)
					_, err = la.Jacobi(Q, λ, A)
					if err != nil {
						failed = true
						return 0
					}
					q2p(k)
					return P[k][i]
				}, a[j], h)
				if failed {
					return
				}
			}
		}
	}
	return
}