moab
|
00001 /* 00002 * CslamUtils.hpp 00003 * 00004 * Created on: Oct 3, 2012 00005 */ 00006 00007 #ifndef CSLAMUTILS_HPP_ 00008 #define CSLAMUTILS_HPP_ 00009 00010 #include "moab/CartVect.hpp" 00011 #include "moab/Core.hpp" 00012 #include "moab/Interface.hpp" 00013 00014 // maximum number of edges on each convex polygon of interest 00015 #define MAXEDGES 10 00016 #define MAXEDGES2 20 // used for coordinates in plane 00017 00018 #define CORRTAGNAME "__correspondent" 00019 00020 namespace moab 00021 { 00022 double dist2(double * a, double * b); 00023 double area2D(double *a, double *b, double *c); 00024 int borderPointsOfXinY2(double * X, int nX, double * Y, int nY, double * P, int side[MAXEDGES], double epsilon_area); 00025 int SortAndRemoveDoubles2(double * P, int & nP, double epsilon); 00026 // the marks will show what edges of blue intersect the red 00027 00028 int EdgeIntersections2(double * blue, int nsBlue, double * red, int nsRed, 00029 int markb[MAXEDGES], int markr[MAXEDGES], double * points, int & nPoints); 00030 00031 // vec utils related to gnomonic projection on a sphere 00032 00033 // vec utils 00034 /* 00035 * 00036 * position on a sphere of radius R 00037 * if plane specified, use it; if not, return the plane, and the point in the plane 00038 * there are 6 planes, numbered 1 to 6 00039 * plane 1: x=R, plane 2: y=R, 3: x=-R, 4: y=-R, 5: z=-R, 6: z=R 00040 * 00041 * projection on the plane will preserve the orientation, such that a triangle, quad pointing 00042 * outside the sphere will have a positive orientation in the projection plane 00043 * this is similar logic to /cesm1_0_4/models/atm/cam/src/dynamics/homme/share/coordinate_systems_mod.F90 00044 * method: function cart2face(cart3D) result(face_no) 00045 */ 00046 void decide_gnomonic_plane(const CartVect & pos, int & oPlane); 00047 // point on a sphere is projected on one of six planes, decided earlier 00048 int gnomonic_projection(const CartVect & pos, double R, int plane, double & c1, double & c2); 00049 // given the position on plane (one out of 6), find out the position on sphere 00050 int reverse_gnomonic_projection(const double & c1, const double & c2, double R, int plane, 00051 CartVect & pos); 00052 00053 /* 00054 * other methods to convert from spherical coord to cartesian, and back 00055 * A spherical coordinate triple is (R, lon, lat) 00056 * should we store it as a CartVect? probably not ... 00057 * /cesm1_0_4/models/atm/cam/src/dynamics/homme/share/coordinate_systems_mod.F90 00058 * 00059 enforce three facts: 00060 ! ========================================================== 00061 ! enforce three facts: 00062 ! 00063 ! 1) lon at poles is defined to be zero 00064 ! 00065 ! 2) Grid points must be separated by about .01 Meter (on earth) 00066 ! from pole to be considered "not the pole". 00067 ! 00068 ! 3) range of lon is { 0<= lon < 2*pi } 00069 ! 00070 ! 4) range of lat is from -pi/2 to pi/2; -pi/2 or pi/2 are the poles, so there the lon is 0 00071 ! 00072 ! ========================================================== 00073 */ 00074 00075 struct SphereCoords{ 00076 double R, lon, lat; 00077 }; 00078 00079 SphereCoords cart_to_spherical(CartVect &) ; 00080 00081 CartVect spherical_to_cart (SphereCoords &) ; 00082 00083 /* 00084 * create a mesh used mainly for visualization for now, with nodes corresponding to 00085 * GL points, a so-called refined mesh, with NP nodes in each direction. 00086 * input: a range of quads (coarse), and a desired order (NP is the number of points), so it 00087 * is order + 1 00088 * 00089 * output: a set with refined elements; with proper input, it should be pretty 00090 * similar to a Homme mesh read with ReadNC 00091 */ 00092 //ErrorCode SpectralVisuMesh(Interface * mb, Range & input, int NP, EntityHandle & outputSet, double tolerance); 00093 00094 /* 00095 * given an entity set, get all nodes and project them on a sphere with given radius 00096 */ 00097 ErrorCode ProjectOnSphere(Interface * mb, EntityHandle set, double R); 00098 00099 bool point_in_interior_of_convex_polygon (double * points, int np, double pt[2]); 00100 00101 /* 00102 * utilities to compute area of a polygon on which all edges are arcs of great circles on a sphere 00103 */ 00104 /* 00105 * this will compute the spherical angle ABC, when A, B, C are on a sphere of radius R 00106 * the radius will not be needed, usually, just for verification the points are indeed on that sphere 00107 * the center of the sphere is at origin (0,0,0) 00108 * this angle can be used in Girard's theorem to compute the area of a spherical polygon 00109 */ 00110 double spherical_angle(double * A, double * B, double * C, double Radius); 00111 00112 // this could be larger than PI, because of orientation; useful for non-convex polygons 00113 double oriented_spherical_angle(double * A, double * B, double * C); 00114 00115 double area_spherical_triangle(double *A, double *B, double *C, double Radius); 00116 00117 double area_spherical_polygon (double * A, int N, double Radius); 00118 00119 double area_spherical_triangle_lHuiller(double * A, double * B, double * C, double Radius); 00120 00121 double area_spherical_polygon_lHuiller (double * A, int N, double Radius); 00122 00123 double area_on_sphere(Interface * mb, EntityHandle set, double R); 00124 00125 double area_on_sphere_lHuiller(Interface * mb, EntityHandle set, double R); 00126 00127 double distance_on_great_circle(CartVect & p1, CartVect & p2); 00128 00129 void departure_point_case1(CartVect & arrival_point, double t, double delta_t, CartVect & departure_point); 00130 00131 void velocity_case1(CartVect & arrival_point, double t, CartVect & velo); 00132 // break the nonconvex quads into triangles; remove the quad from the set? yes. 00133 // maybe radius is not needed; 00134 // 00135 ErrorCode enforce_convexity(Interface * mb, EntityHandle set, int rank = 0); 00136 00137 // looking at DP tag, create the spanning quads, write a file (with rank) and 00138 // then delete the new entities (vertices) and the set of quads 00139 ErrorCode create_span_quads(Interface * mb, EntityHandle euler_set, int rank); 00140 00141 // distance along a great circle on a sphere of radius 1 00142 double distance_on_sphere(double la1, double te1, double la2, double te2); 00143 // page 4 Nair Lauritzen paper 00144 // param will be: (la1, te1), (la2, te2), b, c; hmax=1, r=1/2 00145 double quasi_smooth_field(double lam, double tet, double * params); 00146 // page 4 00147 double smooth_field(double lam, double tet, double * params); 00148 // page 5 00149 double slotted_cylinder_field(double lam, double tet, double * params); 00150 00151 double area_spherical_element(Interface * mb, EntityHandle elem, double R); 00152 00153 00154 } 00155 #endif /* CSLAMUTILS_HPP_ */