source: XIOS/trunk/extern/remap/src/meshutil.cpp @ 844

Last change on this file since 844 was 844, checked in by ymipsl, 6 years ago

Management of masked cell for remapping algorithm.

YM

File size: 4.0 KB
Line 
1#include <list>
2#include "elt.hpp"
3#include "polyg.hpp"
4
5namespace sphereRemap {
6
7using namespace std;
8
9void cptEltGeom(Elt& elt, const Coord &pole)
10{
11  orient(elt.n, elt.vertex, elt.edge, elt.d, elt.x);
12  normals(elt, pole);
13  Coord gg;
14  elt.area = airbar(elt.n, elt.vertex, elt.edge, elt.d, pole, gg);
15  elt.x = gg;
16}
17
18void cptAllEltsGeom(Elt *elt, int N, const Coord &pole)
19{
20  for (int ne=0; ne<N; ne++)
21    cptEltGeom(elt[ne], pole);
22}
23
24/* for all elements of size-N-array `elt`,
25   make centre areaweighted average centres of super mesh elements */
26void update_baryc(Elt *elt, int N)
27{
28  for (int ne=0; ne<N; ne++)
29  {
30    Elt &e = elt[ne];
31    int ns = e.is.size();  // sous-elements
32    Coord *sx = new Coord[ns];
33    int i=0;
34    for (list<Polyg*>::iterator it = e.is.begin(); it != e.is.end(); i++, it++)
35    {
36      sx[i] = (*it)->x * (*it)->area;
37    }
38    e.x = barycentre(sx, ns);
39  }
40}
41
42
43Coord gradient_old(Elt& elt, Elt **neighElts)
44{
45  Coord grad = ORIGIN;
46  Coord *neighBaryc = new Coord[elt.n];
47  for (int j = 0; j < elt.n; j++)
48  {
49    int k = (j + 1) % elt.n;
50    neighBaryc[j] = neighElts[j]->x;
51    Coord edgeNormal = crossprod(neighElts[k]->x, neighElts[j]->x);
52
53    // use nomenclauture form paper
54    double f_i = elt.val;
55    double f_j = neighElts[j]->val;
56    double f_k = neighElts[k]->val;
57    grad = grad + edgeNormal * (0.5*(f_j + f_k) - f_i);
58  }
59  // area of the polygon whoes vertices are the barycentres the neighbours
60  grad = grad * (1./polygonarea(neighBaryc, elt.n));
61  delete[] neighBaryc;
62
63  return grad - elt.x * scalarprod(elt.x, grad);
64}
65
66
67
68Coord gradient(Elt& elt, Elt **neighElts)
69{
70   
71  Coord grad = ORIGIN;
72  Coord neighBaryc[3] ;
73
74  double f_i ;
75  double f_j ;
76  double f_k ;
77 
78  Coord edgeNormal ;
79  double area=0 ;
80  int k ;
81
82  for (int j = 0; j < elt.n; j++)
83  {
84    f_i = elt.val;
85    k = (j + 1) % elt.n;
86    if (neighElts[j]==NULL || neighElts[k]==NULL) continue ;
87
88    // use nomenclauture form paper
89    f_j = neighElts[j]->val;
90    f_k = neighElts[k]->val;
91
92   
93   
94    neighBaryc[0] = elt.x;
95    neighBaryc[1] = neighElts[j]->x;
96    neighBaryc[2] = neighElts[k]->x;
97
98    edgeNormal = crossprod(neighElts[k]->x, neighElts[j]->x);
99    grad = grad + edgeNormal * (0.5*(f_k + f_j) - f_i);
100
101    edgeNormal = crossprod(neighElts[j]->x, elt.x);
102    grad = grad + edgeNormal * (0.5*(f_j + f_i) - f_i);
103
104    edgeNormal = crossprod(elt.x, neighElts[k]->x);
105    grad = grad + edgeNormal * (0.5*(f_i + f_k) - f_i);
106
107  // area of the polygon whoes vertices are the barycentres the neighbours
108
109    area+=polygonarea(neighBaryc, 3) ;
110
111  }
112  grad=grad*(1./area) ;
113  return grad - elt.x * scalarprod(elt.x, grad);
114}
115
116
117
118
119void computeGradients(Elt **elts, int N)
120{
121 
122  for (int j = 0; j < N; j++)
123    elts[j]->val = 0;
124
125  Elt *neighbours[NMAX];
126  for (int j = 0; j < N; j++)
127  {
128    for (int i = 0; i < elts[j]->n; i++) 
129      if ( elts[j]->neighbour[i]== NOT_FOUND) neighbours[i]=NULL ;
130      else  neighbours[i] = elts[elts[j]->neighbour[i]];
131
132    for (int i = 0; i < elts[j]->n; i++)
133      if (neighbours[i]!=NULL) neighbours[i]->val = 0;
134     
135    for (int i = 0; i < elts[j]->n; i++)
136    {
137      if (neighbours[i]!=NULL)
138      {
139        elts[j]->neighId[i] = neighbours[i]->src_id;
140        /* for weight computation all values are always kept zero and only set to one when used .. */
141        neighbours[i]->val = 1;
142        elts[j]->gradNeigh[i] = gradient(*(elts[j]), neighbours);
143        /* .. and right after zeroed again */
144        neighbours[i]->val = 0;
145      }
146      else
147      {
148        elts[j]->neighId[i].rank = -1; // mark end
149        elts[j]->neighId[i].ind = -1; // mark end
150      }
151    }
152
153    for(int i = elts[j]->n ; i < NMAX; i++)
154    {
155      elts[j]->neighId[i].rank = -1; // mark end
156      elts[j]->neighId[i].ind = -1; // mark end
157    }
158    /* For the most naive algorithm the case where the element itself is one must also be considered.
159       Thomas says this can later be optimized out. */
160    elts[j]->val = 1;
161    elts[j]->grad = gradient(*(elts[j]), neighbours);
162    elts[j]->val = 0;
163  }
164}
165
166}
Note: See TracBrowser for help on using the repository browser.