Changeset 2500


Ignore:
Timestamp:
05/12/23 11:34:43 (14 months ago)
Author:
ymipsl
Message:

Modification in remaper to fix problems with non convex cells.

YM

Location:
XIOS2/trunk/extern/remap/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • XIOS2/trunk/extern/remap/src/meshutil.cpp

    r2398 r2500  
    1111using namespace std; 
    1212 
    13 double computePolygoneArea(Elt& a, const Coord &pole) 
     13void computePolygonGeometry(Elt& a, const Coord &pole, double& area, Coord& bary) 
    1414{ 
    1515  using N = uint32_t; 
     
    4949  vector<N> indices_a_gno = mapbox::earcut<N>(polyline); 
    5050   
    51   double area_a_gno=0 ; 
     51  area=0 ; 
    5252  for(int i=0;i<indices_a_gno.size()/3;++i) 
    5353    { 
     
    5555      Coord x1 = Ox * polyline[0][indices_a_gno[3*i+1]][0] + Oy* polyline[0][indices_a_gno[3*i+1]][1] + Oz ; 
    5656      Coord x2 = Ox * polyline[0][indices_a_gno[3*i+2]][0] + Oy* polyline[0][indices_a_gno[3*i+2]][1] + Oz ; 
    57       area_a_gno+=triarea(x0 * (1./norm(x0)),x1* (1./norm(x1)), x2* (1./norm(x2))) ; 
    58     } 
    59  
     57      area+=triarea(x0 * (1./norm(x0)),x1* (1./norm(x1)), x2* (1./norm(x2))) ; 
     58    } 
     59 
     60 
     61  bary = exact_barycentre(dstPolygon.data(),na) ; 
     62   
     63  // check signed area 
     64  double signedArea = 0 ; 
     65  for(int n=0; n<na;n++) signedArea+= a_gno[n].x*a_gno[(n+1)%na].y-a_gno[(n+1)%na].x*a_gno[n].y ; 
     66  if (signedArea<0)  
     67  { 
     68    bary = bary * (-1.) ; 
     69    switchOrientation(a.n, a.vertex,a.edge,a.d) ; 
     70  } 
     71   
    6072  vect_points.clear(); 
    6173  polyline.clear(); 
    6274  indices_a_gno.clear(); 
    63   return area_a_gno ; 
     75 
    6476} 
    6577 
     
    6779void cptEltGeom(Elt& elt, const Coord &pole) 
    6880{ 
    69   orient(elt.n, elt.vertex, elt.edge, elt.d, elt.x); 
    70   normals(elt, pole); 
    71   Coord gg; 
    72   elt.area = airbar(elt.n, elt.vertex, elt.edge, elt.d, pole, gg); 
    73   elt.x = gg; 
     81   orient(elt.n, elt.vertex, elt.edge, elt.d, elt.x); 
     82   normals(elt, pole); 
     83//  Coord gg; 
     84//  elt.area = airbar(elt.n, elt.vertex, elt.edge, elt.d, pole, gg); 
     85//  elt.x = gg; 
    7486// overwrite area computation  
    7587 
    76   elt.area =  computePolygoneArea(elt, pole) ; 
     88   computePolygonGeometry(elt, pole, elt.area, elt.x) ; 
     89   normals(elt, pole); 
     90 
    7791} 
    7892 
  • XIOS2/trunk/extern/remap/src/polyg.cpp

    r1614 r2500  
    1818  (because computing intersection area requires both polygons to have same orientation) 
    1919*/ 
     20 
    2021void orient(int N, Coord *vertex, Coord *edge, double *d, const Coord &g) 
    2122{ 
     
    2425  Coord vertical = crossprod(ga, gb); 
    2526  if (N > 2 && scalarprod(g, vertical) < 0)  // (GAxGB).G 
    26   { 
    27     for (int i = 0; i < N/2; i++) 
    28       swap(vertex[i], vertex[N-1-i]); 
    29  
    30     for (int i = 0; i < (N-1)/2; i++) 
    31     { 
    32       swap(edge[N-2-i], edge[i]); 
    33       swap(d[i], d[N-2-i]); 
    34     } 
    35   } 
    36 } 
    37  
     27    switchOrientation(N, vertex, edge, d) ; 
     28   
     29} 
     30 
     31void switchOrientation(int N, Coord *vertex, Coord *edge, double *d) 
     32{ 
     33  for (int i = 0; i < N/2; i++) swap(vertex[i], vertex[N-1-i]); 
     34 
     35  for (int i = 0; i < (N-1)/2; i++) 
     36  { 
     37    swap(edge[N-2-i], edge[i]); 
     38    swap(d[i], d[N-2-i]); 
     39  } 
     40   
     41} 
    3842 
    3943void normals(Coord *x, int n, Coord *a) 
     
    9498  { 
    9599    return  proj(gc_normalintegral(x, n)); 
     100    //return new_barycentre(x,n) ; 
    96101  } 
    97102  else if (n == 0) return ORIGIN; 
     
    99104  else if (n == 1) return x[0]; 
    100105} 
     106 
     107/* other methode to compute barycenter of spherical polygon 
     108   for a spherical polygon, the moment is half the sum of (a x b) / ||a x b|| * (angle between a and b)  
     109   for each pair of consecutive vertices a,b. 
     110*/  
     111 
     112Coord new_barycentre(const Coord *x, int n) 
     113{ 
     114  if (n >= 3) 
     115  { 
     116    Coord sum=ORIGIN ; 
     117    for (int i = 0; i < n; i++) 
     118    {  
     119      sum=sum+crossprod(x[i],x[(i+1)%n])*(1./norm(crossprod(x[i],x[(i+1)%n]))*2.*atan2(norm(x[i]-x[(i+1)%n]),norm(x[i]+x[(i+1)%n]))) ;  
     120    } 
     121    return proj(sum) ;  
     122  } 
     123  else if (n == 0) return ORIGIN; 
     124  else if (n == 2) return midpoint(x[0], x[1]); 
     125  else if (n == 1) return x[0]; 
     126} 
     127 
     128 
    101129 
    102130Coord sc_gc_moon_normalintegral(Coord a, Coord b, Coord pole) 
  • XIOS2/trunk/extern/remap/src/polyg.hpp

    r1579 r2500  
    77 
    88void orient(int n, Coord *vertex, Coord *edge, double *d, const Coord &g); 
    9  
     9void switchOrientation(int N, Coord *vertex, Coord *edge, double *d) ; 
    1010void normals(Coord *x, int n, Coord *a); 
    1111 
     
    1616double polygonarea(Coord *x, int n); 
    1717Coord exact_barycentre(const Coord *x, int n) ; 
     18Coord new_barycentre(const Coord *x, int n) ; 
    1819 
    1920int packedPolygonSize(const Elt& e); 
Note: See TracChangeset for help on using the changeset viewer.