# Diff of /trunk/ripley/src/Rectangle.cpp

revision 3913 by caltinay, Tue Jun 19 06:21:58 2012 UTC revision 3943 by caltinay, Thu Aug 9 04:43:24 2012 UTC
# Line 32  namespace ripley { Line 32  namespace ripley {
32  Rectangle::Rectangle(int n0, int n1, double x0, double y0, double x1,  Rectangle::Rectangle(int n0, int n1, double x0, double y0, double x1,
33                       double y1, int d0, int d1) :                       double y1, int d0, int d1) :
34      RipleyDomain(2),      RipleyDomain(2),
m_gNE0(n0),
m_gNE1(n1),
35      m_x0(x0),      m_x0(x0),
36      m_y0(y0),      m_y0(y0),
37      m_l0(x1-x0),      m_l0(x1-x0),
38      m_l1(y1-y0),      m_l1(y1-y0)
m_NX(d0),
m_NY(d1)
39  {  {
40        // ignore subdivision parameters for serial run
41        if (m_mpiInfo->size == 1) {
42            d0=1;
43            d1=1;
44        }
45
46        bool warn=false;
47        // if number of subdivisions is non-positive, try to subdivide by the same
48        // ratio as the number of elements
49        if (d0<=0 && d1<=0) {
50            warn=true;
51            d0=(int)(sqrt(m_mpiInfo->size*(n0+1)/(float)(n1+1)));
52            d1=m_mpiInfo->size/d0;
53            if (d0*d1 != m_mpiInfo->size) {
54                // ratios not the same so subdivide side with more elements only
55                if (n0>n1) {
56                    d0=0;
57                    d1=1;
58                } else {
59                    d0=1;
60                    d1=0;
61                }
62            }
63        }
64        if (d0<=0) {
65            // d1 is preset, determine d0 - throw further down if result is no good
66            d0=m_mpiInfo->size/d1;
67        } else if (d1<=0) {
68            // d0 is preset, determine d1 - throw further down if result is no good
69            d1=m_mpiInfo->size/d0;
70        }
71
72        m_NX=d0;
73        m_NY=d1;
74
75      // ensure number of subdivisions is valid and nodes can be distributed      // ensure number of subdivisions is valid and nodes can be distributed
76      // among number of ranks      // among number of ranks
77      if (m_NX*m_NY != m_mpiInfo->size)      if (m_NX*m_NY != m_mpiInfo->size)
78          throw RipleyException("Invalid number of spatial subdivisions");          throw RipleyException("Invalid number of spatial subdivisions");
79
80      if ((n0+1)%m_NX > 0 || (n1+1)%m_NY > 0)      if (warn) {
81          throw RipleyException("Number of elements+1 must be separable into number of ranks in each dimension");          cout << "Warning: Automatic domain subdivision (d0=" << d0 << ", d1="
82                << d1 << "). This may not be optimal!" << endl;
83        }
84
85        if ((n0+1)%m_NX > 0) {
86            double Dx=m_l0/n0;
87            n0=(int)round((float)(n0+1)/d0+0.5)*d0-1;
88            m_l0=Dx*n0;
89            cout << "Warning: Adjusted number of elements and length. N0="
90                << n0 << ", l0=" << m_l0 << endl;
91        }
92        if ((n1+1)%m_NY > 0) {
93            double Dy=m_l1/n1;
94            n1=(int)round((float)(n1+1)/d1+0.5)*d1-1;
95            m_l1=Dy*n1;
96            cout << "Warning: Adjusted number of elements and length. N1="
97                << n1 << ", l1=" << m_l1 << endl;
98        }
99
100        m_gNE0=n0;
101        m_gNE1=n1;
102
103      if ((m_NX > 1 && (n0+1)/m_NX<2) || (m_NY > 1 && (n1+1)/m_NY<2))      if ((m_NX > 1 && (n0+1)/m_NX<2) || (m_NY > 1 && (n1+1)/m_NY<2))
104          throw RipleyException("Too few elements for the number of ranks");          throw RipleyException("Too few elements for the number of ranks");

Legend:
 Removed from v.3913 changed lines Added in v.3943