1 module dsurf.algoritm; 2 3 4 import std.math; 5 import std.range; 6 import std.parallelism; 7 8 import dsurf.cartesian; 9 10 /*********************************** 11 * Set of algoritms to work with cartesian surfaces 12 * Class CartesianSurface represents regular rectangular-cell surface 13 * Authors: Dmitriy Linev 14 * License: MIT 15 * Date: 2019-2020 16 */ 17 18 /// Returns surface gradient along X axis in the node with index i and j 19 double gX(CartesianSurface surface, int i, int j) { 20 if (i == 0) 21 return (surface.z[i + 1][j] - surface.z[i][j]) / surface.dx; 22 if (i == surface.nx - 1) 23 return (surface.z[i][j] - surface.z[i - 1][j]) / surface.dx; 24 return (surface.z[i + 1][j] - surface.z[i - 1][j]) / (2 * surface.dx); 25 } 26 27 /// Returns surface gradient along Y axis in the node with index i and j 28 double gY(CartesianSurface surface, int i, int j) { 29 if (j == 0) 30 return (surface.z[i][j + 1] - surface.z[i][j]) / surface.dy; 31 if (j == surface.ny-1) 32 return (surface.z[i][j] - surface.z[i][j - 1]) / surface.dy; 33 return (surface.z[i][j + 1] - surface.z[i][j - 1]) / (2 * surface.dy); 34 } 35 36 /// Returns CartesianSurface containing gradient map along X axis based on a given surface 37 CartesianSurface buildGradientXMap(CartesianSurface surface) { 38 CartesianSurface gradient = new CartesianSurface(surface); 39 foreach (i; taskPool.parallel(iota(surface.nx))) { 40 foreach (j; 0..surface.ny) { 41 gradient.z[i][j] = surface.gX(i, j); 42 } 43 } 44 return gradient; 45 } 46 47 /// Returns CartesianSurface containing gradient map along Y axis based on a given surface 48 CartesianSurface buildGradientYMap(CartesianSurface surface) { 49 CartesianSurface gradient = new CartesianSurface(surface); 50 foreach (i; taskPool.parallel(iota(surface.nx))) { 51 foreach (j; 0..surface.ny) { 52 gradient.z[i][j] = surface.gY(i, j); 53 } 54 } 55 return gradient; 56 } 57 58 /// Returns dip angle in radians of the surface in the node with index i and j 59 double dipAngle(CartesianSurface surface, int i, int j) { 60 immutable double gx = surface.gX(i, j); 61 immutable double gy = surface.gY(i, j); 62 if (isNaN(gx) || isNaN(gy)) 63 return double.nan; 64 return atan(sqrt(gx * gx + gy * gy)); 65 } 66 67 /// Returns CartesianSurface containing dip angle map in radians based on a given surface 68 CartesianSurface buildDipAngle(CartesianSurface surface) { 69 CartesianSurface result = new CartesianSurface(surface); 70 foreach (i; taskPool.parallel(iota(surface.nx))) { 71 foreach (j; 0..surface.ny) { 72 result.z[i][j] = surface.dipAngle(i, j); 73 } 74 } 75 return result; 76 }