Changeset 24313 for issm/trunk/src/m/mesh/ComputeMetric.py
- Timestamp:
- 11/01/19 12:01:57 (5 years ago)
- Location:
- issm/trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk
-
issm/trunk/src
- Property svn:mergeinfo changed
-
issm/trunk/src/m/mesh/ComputeMetric.py
r21341 r24313 1 1 import numpy as np 2 2 3 def ComputeMetric(hessian,scale,epsilon,hmin,hmax,pos):4 """5 COMPUTEMETRIC - compute metric from an Hessian6 3 7 Usage:8 metric=ComputeMetric(hessian,scale,epsilon,hmin,hmax,pos) 9 pos is contains the positions where the metric is wished to be maximized (water?) 4 def ComputeMetric(hessian, scale, epsilon, hmin, hmax, pos): 5 """ 6 COMPUTEMETRIC - compute metric from an Hessian 10 7 11 Example:12 metric=ComputeMetric(hessian,2/9,10^-1,100,10^5,[])13 """ 8 Usage: 9 metric = ComputeMetric(hessian, scale, epsilon, hmin, hmax, pos) 10 pos is contains the positions where the metric is wished to be maximized (water?) 14 11 15 #first, find the eigen values of each line of H=[hessian(i,1) hessian(i,2); hessian(i,2) hessian(i,3)] 16 a=hessian[:,0] 17 b=hessian[:,1] 18 d=hessian[:,2] 19 lambda1=0.5*((a+d)+np.sqrt(4.*b**2+(a-d)**2)) 20 lambda2=0.5*((a+d)-np.sqrt(4.*b**2+(a-d)**2)) 21 pos1=np.nonzero(lambda1==0.)[0] 22 pos2=np.nonzero(lambda2==0.)[0] 23 pos3=np.nonzero(np.logical_and(b==0.,lambda1==lambda2))[0] 12 Example: 13 metric = ComputeMetric(hessian, 2 / 9, 1.0e-1, 100, 1.0e5, []) 14 """ 24 15 25 #Modify the eigen values to control the shape of the elements 26 lambda1=np.minimum(np.maximum(np.abs(lambda1)*scale/epsilon,1./hmax**2),1./hmin**2) 27 lambda2=np.minimum(np.maximum(np.abs(lambda2)*scale/epsilon,1./hmax**2),1./hmin**2) 16 #first, find the eigen values of each line of H = [hessian(i, 1) hessian(i, 2); hessian(i, 2) hessian(i, 3)] 17 a = hessian[:, 0] 18 b = hessian[:, 1] 19 d = hessian[:, 2] 20 lambda1 = 0.5 * ((a + d) + np.sqrt(4. * b**2 + (a - d)**2)) 21 lambda2 = 0.5 * ((a + d) - np.sqrt(4. * b**2 + (a - d)**2)) 22 pos1 = np.nonzero(lambda1 == 0.)[0] 23 pos2 = np.nonzero(lambda2 == 0.)[0] 24 pos3 = np.nonzero(np.logical_and(b == 0., lambda1 == lambda2))[0] 28 25 29 #compute eigen vectors 30 norm1=np.sqrt(8.*b**2+2.*(d-a)**2+2.*(d-a)*np.sqrt((a-d)**2+4.*b**2)) 31 v1x=2.*b/norm1 32 v1y=((d-a)+np.sqrt((a-d)**2+4.*b**2))/norm1 33 norm2=np.sqrt(8.*b**2+2.*(d-a)**2-2.*(d-a)*np.sqrt((a-d)**2+4.*b**2)) 34 v2x=2.*b/norm2 35 v2y=((d-a)-np.sqrt((a-d)**2+4.*b**2))/norm2 26 #Modify the eigen values to control the shape of the elements 27 lambda1 = np.minimum(np.maximum(np.abs(lambda1) * scale / epsilon, 1. / hmax**2), 1. / hmin**2) 28 lambda2 = np.minimum(np.maximum(np.abs(lambda2) * scale / epsilon, 1. / hmax**2), 1. / hmin**2) 36 29 37 v1x[pos3]=1. 38 v1y[pos3]=0. 39 v2x[pos3]=0. 40 v2y[pos3]=1. 30 #compute eigen vectors 31 norm1 = np.sqrt(8. * b**2 + 2. * (d - a)**2 + 2. * (d - a) * np.sqrt((a - d)**2 + 4. * b**2)) 32 v1x = 2. * b / norm1 33 v1y = ((d - a) + np.sqrt((a - d)**2 + 4. * b**2)) / norm1 34 norm2 = np.sqrt(8. * b**2 + 2. * (d - a)**2 - 2. * (d - a) * np.sqrt((a - d)**2 + 4. * b**2)) 35 v2x = 2. * b / norm2 36 v2y = ((d - a) - np.sqrt((a - d)**2 + 4. * b**2)) / norm2 41 37 42 #Compute new metric (for each node M=V*Lambda*V^-1) 43 metric=np.vstack((((v1x*v2y-v1y*v2x)**(-1)*( lambda1*v2y*v1x-lambda2*v1y*v2x)).reshape(-1,), 44 ((v1x*v2y-v1y*v2x)**(-1)*( lambda1*v1y*v2y-lambda2*v1y*v2y)).reshape(-1,), 45 ((v1x*v2y-v1y*v2x)**(-1)*(-lambda1*v2x*v1y+lambda2*v1x*v2y)).reshape(-1,))).T 38 v1x[pos3] = 1. 39 v1y[pos3] = 0. 40 v2x[pos3] = 0. 41 v2y[pos3] = 1. 46 42 47 #some corrections for 0 eigen values 48 metric[pos1,:]=np.tile(np.array([[1./hmax**2,0.,1./hmax**2]]),(np.size(pos1),1)) 49 metric[pos2,:]=np.tile(np.array([[1./hmax**2,0.,1./hmax**2]]),(np.size(pos2),1)) 43 #Compute new metric (for each node M = V * Lambda * V^-1) 50 44 51 #take care of water elements 52 metric[pos ,:]=np.tile(np.array([[1./hmax**2,0.,1./hmax**2]]),(np.size(pos ),1)) 45 metric = np.vstack((((v1x * v2y - v1y * v2x)**(-1) * (lambda1 * v2y * v1x - lambda2 * v1y * v2x)).reshape(-1, ), 46 ((v1x * v2y - v1y * v2x)**(-1) * (lambda1 * v1y * v2y - lambda2 * v1y * v2y)).reshape(-1, ), 47 ((v1x * v2y - v1y * v2x)**(-1) * (-lambda1 * v2x * v1y + lambda2 * v1x * v2y)).reshape(-1, ))).T 53 48 54 #take care of NaNs if any (use Numpy eig in a loop) 55 pos=np.nonzero(np.isnan(metric))[0] 56 if np.size(pos): 57 print(" %i NaN found in the metric. Use Numpy routine..." % np.size(pos)) 58 for posi in pos: 59 H=np.array([[hessian[posi,0],hessian[posi,1]],[hessian[posi,1],hessian[posi,2]]]) 60 [v,u]=np.linalg.eig(H) 61 v=np.diag(v) 62 lambda1=v[0,0] 63 lambda2=v[1,1] 64 v[0,0]=np.minimum(np.maximum(np.abs(lambda1)*scale/epsilon,1./hmax**2),1./hmin**2) 65 v[1,1]=np.minimum(np.maximum(np.abs(lambda2)*scale/epsilon,1./hmax**2),1./hmin**2) 49 #some corrections for 0 eigen values 50 metric[pos1, :] = np.tile(np.array([[1. / hmax**2, 0., 1. / hmax**2]]), (np.size(pos1), 1)) 51 metric[pos2, :] = np.tile(np.array([[1. / hmax**2, 0., 1. / hmax**2]]), (np.size(pos2), 1)) 66 52 67 metricTria=np.dot(np.dot(u,v),np.linalg.inv(u)) 68 metric[posi,:]=np.array([metricTria[0,0],metricTria[0,1],metricTria[1,1]])53 #take care of water elements 54 metric[pos, :] = np.tile(np.array([[1. / hmax**2, 0., 1. / hmax**2]]), (np.size(pos), 1)) 69 55 70 if np.any(np.isnan(metric)): 71 raise RunTimeError("ComputeMetric error message: NaN in the metric despite our efforts...") 56 #take care of NaNs if any (use Numpy eig in a loop) 57 pos = np.nonzero(np.isnan(metric))[0] 58 if np.size(pos): 59 print((" %i NaN found in the metric. Use Numpy routine..." % np.size(pos))) 60 for posi in pos: 61 H = np.array([[hessian[posi, 0], hessian[posi, 1]], [hessian[posi, 1], hessian[posi, 2]]]) 62 [v, u] = np.linalg.eig(H) 63 v = np.diag(v) 64 lambda1 = v[0, 0] 65 lambda2 = v[1, 1] 66 v[0, 0] = np.minimum(np.maximum(np.abs(lambda1) * scale / epsilon, 1. / hmax**2), 1. / hmin**2) 67 v[1, 1] = np.minimum(np.maximum(np.abs(lambda2) * scale / epsilon, 1. / hmax**2), 1. / hmin**2) 72 68 73 return metric 69 metricTria = np.dot(np.dot(u, v), np.linalg.inv(u)) 70 metric[posi, :] = np.array([metricTria[0, 0], metricTria[0, 1], metricTria[1, 1]]) 74 71 72 if np.any(np.isnan(metric)): 73 raise RunTimeError("ComputeMetric error message: NaN in the metric despite our efforts...") 74 75 return metric
Note:
See TracChangeset
for help on using the changeset viewer.