oomph::StefanBoltzmannHelper Namespace Reference

Namespace containing helper functions for Stefan Boltzmann radiation. More...

Functions

Vector< doubleMax_coord (2,-DBL_MAX)
 Max bin coords. More...
 
Vector< doubleMin_coord (2, DBL_MAX)
 Min bin coords. More...
 
Vector< doubleDx (2, 0.0)
 Increments in bin. More...
 
void bin_helper (const Vector< Vector< double > > &ray_vertex, const bool &populate_bin, Vector< std::pair< unsigned, unsigned > > &intersected_bin, FiniteElement *el_pt, std::ofstream &outfile)
 
void doc_bins (std::ofstream &bin_file)
 
void doc_sample_points (std::ofstream &outfile, const Vector< FiniteElement * > &sb_face_element_pt)
 
void setup_stefan_boltzmann_visibility (const Vector< FiniteElement * > &sb_face_element_pt)
 

Variables

Vector< Vector< std::set< FiniteElement * > > > Element_in_bin
 Bin to store pointers to finite elements in. More...
 
unsigned Nx_bin =1000
 Number of bins in x direction. More...
 
unsigned Ny_bin =1000
 Number of bins in y direction. More...
 
unsigned Nsample =10
 

Detailed Description

Namespace containing helper functions for Stefan Boltzmann radiation.

/////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////

Function Documentation

◆ bin_helper()

void oomph::StefanBoltzmannHelper::bin_helper ( const Vector< Vector< double > > &  ray_vertex,
const bool populate_bin,
Vector< std::pair< unsigned, unsigned > > &  intersected_bin,
FiniteElement el_pt,
std::ofstream &  outfile 
)

Helper function to setup or use bin that is used to locate intersections of rays with boundaries.

Args: – Two vectors, ray_vertex[0] and ray_vertex[1] which define the end points of a ray. – Boolean populate_bin: Element_in_bin by associating all bins that are intersected by the ray with the element pointed to by el_pt. If false: Return vector of bin indices that are intersected by the ray (retrived from previously set up bin structure) – Output stream outfile; if open, we write the intersected bins to that file but only if populate_bin=false. Only used for debugging...

1866  {
1867 
1868  // Actually plot
1869  bool plot_it=false;
1870  if (outfile.is_open())
1871  {
1872  if (populate_bin)
1873  {
1874  //Issue a warning
1875  OomphLibWarning(
1876  "Not outputting while bin is being populated...\n",
1879  }
1880  else
1881  {
1882  plot_it=true;
1883  }
1884  }
1885 
1886  // Step along ray in increasing y direction
1887  Vector<double> lower_ray_vertex=ray_vertex[0];
1888  Vector<double> upper_ray_vertex=ray_vertex[1];
1889  if (ray_vertex[1][1]<ray_vertex[0][1])
1890  {
1891  lower_ray_vertex=ray_vertex[1];
1892  upper_ray_vertex=ray_vertex[0];
1893  }
1894 
1895  // Output
1896  if (plot_it)
1897  {
1898  outfile
1899  << "ZONE T=\"ray\"\n"
1900  <<ray_vertex[0][0] << " " << ray_vertex[0][1] << "\n"
1901  <<ray_vertex[1][0] << " " << ray_vertex[1][1] << "\n";
1902  }
1903 
1904  // Add bin that contains the start point of the ray
1905  unsigned ix_start=unsigned((lower_ray_vertex[0]-Min_coord[0])/
1906  (Max_coord[0]-Min_coord[0])*
1907  double(Nx_bin));
1908  unsigned iy_start=unsigned((lower_ray_vertex[1]-Min_coord[1])/
1909  (Max_coord[1]-Min_coord[1])*
1910  double(Ny_bin));
1911  if (populate_bin)
1912  {
1913  Element_in_bin[ix_start][iy_start].insert(el_pt);
1914  }
1915  else
1916  {
1917  intersected_bin.push_back(std::make_pair(ix_start,iy_start));
1918  }
1919 
1920  // Vertical ray?
1921  if (lower_ray_vertex[0]==upper_ray_vertex[0])
1922  {
1923  // Add all the bins above the initial one until end point
1924  unsigned iy_end=unsigned((upper_ray_vertex[1]-Min_coord[1])/
1925  (Max_coord[1]-Min_coord[1])*
1926  double(Ny_bin));
1927  for (unsigned i=iy_start+1;i<=iy_end;i++)
1928  {
1929  if (populate_bin)
1930  {
1931  Element_in_bin[ix_start][i].insert(el_pt);
1932  }
1933  else
1934  {
1935  intersected_bin.push_back(std::make_pair(ix_start,i));
1936  }
1937  }
1938  }
1939  // Non-vertical ray
1940  else
1941  {
1942  // Get the (finite) slope
1943  double slope=
1944  (upper_ray_vertex[1]-lower_ray_vertex[1])/
1945  (upper_ray_vertex[0]-lower_ray_vertex[0]);
1946 
1947  // Current bin level
1948  unsigned iy=iy_start;
1949 
1950  // Upper and lower bounds of current bin level
1951  double y_this_bin_min=Min_coord[1]+double(iy )*Dx[1];
1952  double y_this_bin_max=Min_coord[1]+double(iy+1)*Dx[1];
1953 
1954  // Keep going until we've moved through all the
1955  // bins beyond the y-level of the ray's end point
1956  int unit_offset=1;
1957  while (y_this_bin_min<upper_ray_vertex[1])
1958  {
1959  // Work out x-coordinate of intersection of ray with
1960  // other boundary of its current y-bin level
1961  double x_intersect=Max_coord[0];
1962  if (lower_ray_vertex[0]>upper_ray_vertex[0])
1963  {
1964  x_intersect=Min_coord[0];
1965  }
1966  if (slope!=0.0)
1967  {
1968  x_intersect=lower_ray_vertex[0]+
1969  (y_this_bin_max-lower_ray_vertex[1])/slope;
1970  }
1971 
1972  // Cut it off if it goes outside the bin structure
1973  if (x_intersect>Max_coord[0]) x_intersect=Max_coord[0] ;
1974  if (x_intersect<Min_coord[0]) x_intersect=Min_coord[0] ;
1975 
1976  // What's the x-bin index of that point
1977  unsigned ix_intersect=unsigned((x_intersect-Min_coord[0])/
1978  (Max_coord[0]-Min_coord[0])*
1979  double(Nx_bin));
1980 
1981  // limits for x bins:
1982  unsigned i_lo=ix_start;
1983  unsigned i_hi=ix_intersect;
1984 
1985  // Swap if going to the left and apply
1986  // unit offset. Equal to one initially because the first
1987  // bin has already been filled; in subsequent rows of
1988  // bins, we add all of them.
1989  if (i_lo>i_hi)
1990  {
1991  i_lo=ix_intersect;
1992  i_hi=ix_start-unit_offset;
1993  }
1994  else
1995  {
1996  i_lo+=unit_offset;
1997  }
1998  unit_offset=0;
1999 
2000  // ...but don't fall off the end...
2001  if (i_hi==Nx_bin) i_hi-=1;
2002 
2003  // Now add all the bins at this y-level
2004  for (unsigned i=i_lo;i<=i_hi;i++)
2005  {
2006  // .. but don't go beyond the end of the ray
2007  bool add_it=true;
2008  if (slope>0.0)
2009  {
2010  double x_left_end_bin =Min_coord[0]+double(i )*Dx[0];
2011  if (x_left_end_bin>upper_ray_vertex[0])
2012  {
2013  add_it=false;
2014  }
2015  }
2016  else if (slope<0.0)
2017  {
2018  double x_right_end_bin=Min_coord[0]+double(i+1)*Dx[0];
2019  if (x_right_end_bin<upper_ray_vertex[0])
2020  {
2021  add_it=false;
2022  }
2023  }
2024  else
2025  {
2026  double x_left_end_bin =Min_coord[0]+double(i )*Dx[0];
2027  double x_right_end_bin=Min_coord[0]+double(i+1)*Dx[0];
2028  if (x_left_end_bin>std::max(upper_ray_vertex[0],lower_ray_vertex[0]))
2029  {
2030  add_it=false;
2031  }
2032  else if (x_right_end_bin<std::min(upper_ray_vertex[0],
2033  lower_ray_vertex[0]))
2034  {
2035  add_it=false;
2036  }
2037  }
2038 
2039  if (add_it)
2040  {
2041  if (populate_bin)
2042  {
2043  Element_in_bin[i][iy].insert(el_pt);
2044  }
2045  else
2046  {
2047  intersected_bin.push_back(std::make_pair(i,iy));
2048  }
2049  }
2050  }
2051 
2052  // Now update the counters: x bin level starts at the
2053  // point of intersection with the next level...
2054  ix_start=ix_intersect;
2055 
2056  // ...upper and lower boundary moves one level up
2057  y_this_bin_min+=Dx[1];
2058  y_this_bin_max+=Dx[1];
2059 
2060  // ...and bump up the level itself
2061  iy++;
2062  }
2063  }
2064 
2065  // Plot the intersected bins?
2066  if (plot_it)
2067  {
2068  unsigned nbin=intersected_bin.size();
2069  for (unsigned i=0;i<nbin;i++)
2070  {
2071  unsigned ix=intersected_bin[i].first;
2072  unsigned iy=intersected_bin[i].second;
2073 
2074  double x_lo=Min_coord[0]+double(ix)*Dx[0];
2075  double x_hi=x_lo+Dx[0];
2076  double y_lo=Min_coord[1]+double(iy)*Dx[1];
2077  double y_hi=y_lo+Dx[1];
2078 
2079  outfile << "ZONE\n"
2080  << x_lo << " " << y_lo << "\n"
2081  << x_hi << " " << y_lo << "\n"
2082  << x_hi << " " << y_hi << "\n"
2083  << x_lo << " " << y_hi << "\n"
2084  << x_lo << " " << y_lo << "\n";
2085  }
2086  }
2087  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
#define min(a, b)
Definition: datatypes.h:22
#define max(a, b)
Definition: datatypes.h:23
void plot_it(const std::string filename)
Plot "landscape" of residuals (only for 2D problems!)
Definition: spring_contact.cc:211
unsigned Nx_bin
Number of bins in x direction.
Definition: temporary_stefan_boltzmann_elements.h:1833
Vector< double > Dx(2, 0.0)
Increments in bin.
unsigned Ny_bin
Number of bins in y direction.
Definition: temporary_stefan_boltzmann_elements.h:1836
Vector< double > Min_coord(2, DBL_MAX)
Min bin coords.
Vector< double > Max_coord(2,-DBL_MAX)
Max bin coords.
Vector< Vector< std::set< FiniteElement * > > > Element_in_bin
Bin to store pointers to finite elements in.
Definition: temporary_stefan_boltzmann_elements.h:1821
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References Dx(), Element_in_bin, i, max, Max_coord(), min, Min_coord(), Nx_bin, Ny_bin, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and GlobalFct::plot_it().

Referenced by setup_stefan_boltzmann_visibility().

◆ doc_bins()

void oomph::StefanBoltzmannHelper::doc_bins ( std::ofstream &  bin_file)
2094  {
2095  // Loop over bins
2096  for (unsigned ix=0;ix<Nx_bin;ix++)
2097  {
2098  for (unsigned iy=0;iy<Ny_bin;iy++)
2099  {
2100  // Anybody at home?
2101  if (Element_in_bin[ix][iy].size()!=0)
2102  {
2103  double x_lo=Min_coord[0]+double(ix)*Dx[0];
2104  double x_hi=x_lo+Dx[0];
2105  double y_lo=Min_coord[1]+double(iy)*Dx[1];
2106  double y_hi=y_lo+Dx[1];
2107 
2108  bin_file << "ZONE I=2, J=2\n"
2109  << x_lo << " " << y_lo << "\n"
2110  << x_hi << " " << y_lo << "\n"
2111  << x_lo << " " << y_hi << "\n"
2112  << x_hi << " " << y_hi << "\n";
2113 
2114  }
2115  }
2116  }
2117  }
Scalar Scalar int size
Definition: benchVecAdd.cpp:17

References Dx(), Element_in_bin, Min_coord(), Nx_bin, Ny_bin, and size.

Referenced by StefanBoltzmannProblem< ELEMENT >::setup_sb_radiation(), and StefanBoltzmannProblem< ELEMENT >::StefanBoltzmannProblem().

◆ doc_sample_points()

void oomph::StefanBoltzmannHelper::doc_sample_points ( std::ofstream &  outfile,
const Vector< FiniteElement * > &  sb_face_element_pt 
)
2126  {
2127  // Vector for coordinates of sample point
2128  Vector<double> sample_point(2);
2129  Vector<double> s(1);
2130 
2131  // Loop over all face elements
2132  unsigned nel=sb_face_element_pt.size();
2133  for (unsigned e=0;e<nel;e++)
2134  {
2135  StefanBoltzmannRadiationBase* el_pt=
2136  dynamic_cast<StefanBoltzmannRadiationBase*>(
2137  sb_face_element_pt[e]);
2138 #ifdef PARANOID
2139  if (el_pt==0)
2140  {
2141  std::stringstream error_message;
2142  error_message << "Failed to cast possible intersecting element "
2143  << e
2144  << " to StefanBoltzmannRadiationBase";
2145  throw OomphLibError(
2146  error_message.str(),
2149  }
2150 #endif
2151 
2152  // Loop over sampling points
2153  for (unsigned j_sample=0;j_sample<Nsample;j_sample++)
2154  {
2155  // Get vector of local coordinates of plot point j
2156  // as second vertex
2157  el_pt->get_s_plot(j_sample,Nsample,s);
2158 
2159  // Get coordinate of vertex
2160  el_pt->interpolated_x(s,sample_point);
2161 
2162  outfile << sample_point[0] << " " << sample_point[1] << "\n";
2163  }
2164  }
2165  }
Array< double, 1, 3 > e(1./3., 0.5, 2.)
RealScalar s
Definition: level1_cplx_impl.h:130
unsigned Nsample
Definition: temporary_stefan_boltzmann_elements.h:1840

References e(), oomph::FiniteElement::get_s_plot(), oomph::FiniteElement::interpolated_x(), Nsample, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and s.

Referenced by StefanBoltzmannProblem< ELEMENT >::setup_sb_radiation(), and StefanBoltzmannProblem< ELEMENT >::StefanBoltzmannProblem().

◆ Dx()

Vector<double> oomph::StefanBoltzmannHelper::Dx ( ,
0.  0 
)

◆ Max_coord()

Vector<double> oomph::StefanBoltzmannHelper::Max_coord ( ,
DBL_MAX 
)

Max bin coords.

Referenced by bin_helper(), and setup_stefan_boltzmann_visibility().

◆ Min_coord()

Vector<double> oomph::StefanBoltzmannHelper::Min_coord ( ,
DBL_MAX   
)

Min bin coords.

Referenced by bin_helper(), doc_bins(), and setup_stefan_boltzmann_visibility().

◆ setup_stefan_boltzmann_visibility()

void oomph::StefanBoltzmannHelper::setup_stefan_boltzmann_visibility ( const Vector< FiniteElement * > &  sb_face_element_pt)

Setup mutual visibility for Stefan Boltzmann radiation for all face elements (derived from StefanBoltzmannRadiationBase) contained in vector.

2175  {
2176  // Output file for debugging
2177  const bool plot_it=false;
2178  std::ofstream some_file;
2179  char filename[100];
2180 
2181  // Loop over all face elements to wipe previous information
2182  unsigned nel=sb_face_element_pt.size();
2183  for (unsigned e_illuminated=0;e_illuminated<nel;e_illuminated++)
2184  {
2185  StefanBoltzmannRadiationBase* illuminated_el_pt=
2186  dynamic_cast<StefanBoltzmannRadiationBase*>(
2187  sb_face_element_pt[e_illuminated]);
2188 #ifdef PARANOID
2189  if (illuminated_el_pt==0)
2190  {
2191  std::stringstream error_message;
2192  error_message << "Failed to cast illuminated element "
2193  << e_illuminated
2194  << " to StefanBoltzmannRadiationBase";
2195  throw OomphLibError(
2196  error_message.str(),
2199  }
2200 #endif
2201 
2202  // Forget any previous information
2203  illuminated_el_pt->wipe_stefan_boltzmann_illumination_info();
2204  }
2205 
2206 
2207  double t_start=TimingHelpers::timer();
2208 
2209  // Vector to illuminated/ing Gauss points
2210  Vector<double> r_illuminated(2);
2211  Vector<double> s_illuminated(1);
2212  Vector<double> unit_normal_illuminated(2);
2213  Vector<double> r_illuminating(2);
2214  Vector<double> s_illuminating(1);
2215  Vector<double> unit_normal_illuminating(2);
2216 
2217  // Setup bin structure
2218  const bool use_bins=true;
2219  if (use_bins)
2220  {
2221  double t_start_bin=TimingHelpers::timer();
2222 
2223  // Each bin stores FiniteElements that have any sample point in it
2224  Element_in_bin.clear();
2225  Element_in_bin.resize(Nx_bin);
2226  for (unsigned i=0;i<Nx_bin;i++)
2227  {
2228  Element_in_bin[i].resize(Ny_bin);
2229  }
2230 
2231 
2232  // Reset max/min coords
2233  Max_coord.clear();
2234  Max_coord.resize(2,-DBL_MAX);
2235  Min_coord.clear();
2236  Min_coord.resize(2, DBL_MAX);
2237 
2238  // Initial sweep: Get max/min coords
2239  //----------------------------------
2240 
2241  // Loop over all face elements
2242  unsigned nel=sb_face_element_pt.size();
2243  for (unsigned e_illuminated=0;e_illuminated<nel;e_illuminated++)
2244  {
2245  StefanBoltzmannRadiationBase* illuminated_el_pt=
2246  dynamic_cast<StefanBoltzmannRadiationBase*>(
2247  sb_face_element_pt[e_illuminated]);
2248 #ifdef PARANOID
2249  if (illuminated_el_pt==0)
2250  {
2251  std::stringstream error_message;
2252  error_message << "Failed to cast illuminated element "
2253  << e_illuminated
2254  << " to StefanBoltzmannRadiationBase";
2255  throw OomphLibError(
2256  error_message.str(),
2259  }
2260 #endif
2261 
2262  // Loop over iluminated integration points
2263  unsigned nint=illuminated_el_pt->integral_pt()->nweight();
2264  for (unsigned ipt_illuminated=0;ipt_illuminated<nint;ipt_illuminated++)
2265  {
2266  // Local coordinate of integration point
2267  s_illuminated[0]=
2268  illuminated_el_pt->integral_pt()->knot(ipt_illuminated,0);
2269 
2270  // No recycling of shape fcts -- may as well call interpolated_x
2271  // directly
2272  illuminated_el_pt->interpolated_x(s_illuminated,r_illuminated);
2273 
2274  for (unsigned i=0;i<2;i++)
2275  {
2276  if (r_illuminated[i]>Max_coord[i]) Max_coord[i]=r_illuminated[i];
2277  if (r_illuminated[i]<Min_coord[i]) Min_coord[i]=r_illuminated[i];
2278  }
2279  }
2280  }
2281 
2282  // Allow for offset
2283  double percentage_offset=5.0;
2284  for (unsigned i=0;i<2;i++)
2285  {
2286  double dx=Max_coord[i]-Min_coord[i];
2287  Max_coord[i]=Max_coord[i]+percentage_offset/100.0*dx;
2288  Min_coord[i]=Min_coord[i]-percentage_offset/100.0*dx;
2289  }
2290 
2291  // Update increments
2292  Dx[0]=(Max_coord[0]-Min_coord[0])/double(Nx_bin);
2293  Dx[1]=(Max_coord[1]-Min_coord[1])/double(Ny_bin);
2294 
2295 
2296  const bool test_horizontal_and_vertical_rays=false;
2297  if (test_horizontal_and_vertical_rays)
2298  {
2299 
2300  // Test for left to right horizontal ray
2301  {
2302  // Populate bin by associating all bins intersected by
2303  // ray from one to the other sample vertex with the
2304  // element (note that the ray can span multiple bins!)
2305  Vector<std::pair<unsigned,unsigned> > dummy_intersected_bin;
2306  bool populate_bin=true;
2307  std::ofstream dummy_file;
2308  Vector<Vector<double> > sample_vertex(2);
2309  sample_vertex[0].resize(2);
2310  sample_vertex[1].resize(2);
2311  sample_vertex[0][0]=-0.9;
2312  sample_vertex[0][1]=0.9;
2313  sample_vertex[1][0]=0.9;
2314  sample_vertex[1][1]=0.9;
2315 
2316  StefanBoltzmannRadiationBase* el_pt=
2317  dynamic_cast<StefanBoltzmannRadiationBase*>(
2318  sb_face_element_pt[0]);
2319 
2320  bin_helper(sample_vertex,
2321  populate_bin,
2322  dummy_intersected_bin,
2323  el_pt,
2324  dummy_file);
2325  }
2326 
2327 
2328 
2329 
2330  // Test for right to left horizontal ray
2331  {
2332  // Populate bin by associating all bins intersected by
2333  // ray from one to the other sample vertex with the
2334  // element (note that the ray can span multiple bins!)
2335  Vector<std::pair<unsigned,unsigned> > dummy_intersected_bin;
2336  bool populate_bin=true;
2337  std::ofstream dummy_file;
2338  Vector<Vector<double> > sample_vertex(2);
2339  sample_vertex[0].resize(2);
2340  sample_vertex[1].resize(2);
2341  sample_vertex[0][0]= 0.9;
2342  sample_vertex[0][1]=-0.9;
2343  sample_vertex[1][0]=-0.9;
2344  sample_vertex[1][1]=-0.9;
2345 
2346  StefanBoltzmannRadiationBase* el_pt=
2347  dynamic_cast<StefanBoltzmannRadiationBase*>(
2348  sb_face_element_pt[0]);
2349 
2350  bin_helper(sample_vertex,
2351  populate_bin,
2352  dummy_intersected_bin,
2353  el_pt,
2354  dummy_file);
2355  }
2356 
2357 
2358  // Test for bottom to top vertical ray
2359  {
2360  // Populate bin by associating all bins intersected by
2361  // ray from one to the other sample vertex with the
2362  // element (note that the ray can span multiple bins!)
2363  Vector<std::pair<unsigned,unsigned> > dummy_intersected_bin;
2364  bool populate_bin=true;
2365  std::ofstream dummy_file;
2366  Vector<Vector<double> > sample_vertex(2);
2367  sample_vertex[0].resize(2);
2368  sample_vertex[1].resize(2);
2369  sample_vertex[0][0]=-0.7;
2370  sample_vertex[0][1]=-0.9;
2371  sample_vertex[1][0]=-0.7;
2372  sample_vertex[1][1]= 0.9;
2373 
2374  StefanBoltzmannRadiationBase* el_pt=
2375  dynamic_cast<StefanBoltzmannRadiationBase*>(
2376  sb_face_element_pt[0]);
2377 
2378  bin_helper(sample_vertex,
2379  populate_bin,
2380  dummy_intersected_bin,
2381  el_pt,
2382  dummy_file);
2383  }
2384 
2385 
2386  // Test for to to bottom vertical ray
2387  {
2388  // Populate bin by associating all bins intersected by
2389  // ray from one to the other sample vertex with the
2390  // element (note that the ray can span multiple bins!)
2391  Vector<std::pair<unsigned,unsigned> > dummy_intersected_bin;
2392  bool populate_bin=true;
2393  std::ofstream dummy_file;
2394  Vector<Vector<double> > sample_vertex(2);
2395  sample_vertex[0].resize(2);
2396  sample_vertex[1].resize(2);
2397  sample_vertex[0][0]= 0.7;
2398  sample_vertex[0][1]= 0.9;
2399  sample_vertex[1][0]= 0.7;
2400  sample_vertex[1][1]=-0.9;
2401 
2402  StefanBoltzmannRadiationBase* el_pt=
2403  dynamic_cast<StefanBoltzmannRadiationBase*>(
2404  sb_face_element_pt[0]);
2405 
2406  bin_helper(sample_vertex,
2407  populate_bin,
2408  dummy_intersected_bin,
2409  el_pt,
2410  dummy_file);
2411  }
2412 
2413  } // end of test for horizontal and vertical rays
2414 
2415  // Setup bin for checking intersections with rays
2416  //-----------------------------------------------
2417 
2418  // Loop over all face elements
2419  nel=sb_face_element_pt.size();
2420  for (unsigned e=0;e<nel;e++)
2421  {
2422  StefanBoltzmannRadiationBase* el_pt=
2423  dynamic_cast<StefanBoltzmannRadiationBase*>(
2424  sb_face_element_pt[e]);
2425 #ifdef PARANOID
2426  if (el_pt==0)
2427  {
2428  std::stringstream error_message;
2429  error_message << "Failed to cast possible intersecting element "
2430  << e
2431  << " to StefanBoltzmannRadiationBase";
2432  throw OomphLibError(
2433  error_message.str(),
2436  }
2437 #endif
2438 
2439  // Loop over ALL sampling points along element
2440  Vector<Vector<double> > sample_vertex(2);
2441  sample_vertex[0].resize(2);
2442  sample_vertex[1].resize(2);
2443 
2444  // Get vector of local coordinates of plot point j
2445  // as first vertex
2446  Vector<double> s(1);
2447  unsigned j_sample=0;
2448  el_pt->get_s_plot(j_sample,Nsample,s);
2449 
2450  // Get coordinate of first vertex
2451  el_pt->interpolated_x(s,sample_vertex[0]);
2452 
2453  // Loop over remaining sampling points
2454  for (unsigned j_sample=1;j_sample<Nsample;j_sample++)
2455  {
2456  // Get vector of local coordinates of plot point j
2457  // as second vertex
2458  el_pt->get_s_plot(j_sample,Nsample,s);
2459 
2460  // Get coordinate of vertex
2461  el_pt->interpolated_x(s,sample_vertex[1]);
2462 
2463  // Populate bin by associating all bins intersected by
2464  // ray from one to the other sample vertex with the
2465  // element (note that the ray can span multiple bins!)
2466  Vector<std::pair<unsigned,unsigned> > dummy_intersected_bin;
2467  bool populate_bin=true;
2468  std::ofstream dummy_file;
2469  bin_helper(sample_vertex,
2470  populate_bin,
2471  dummy_intersected_bin,
2472  el_pt,
2473  dummy_file);
2474 
2475  // Shift along
2476  sample_vertex[0]=sample_vertex[1];
2477  }
2478  }
2479 
2480  double t_end_bin=TimingHelpers::timer();
2481  oomph_info << "Time for setting up bin: "
2482  << t_end_bin-t_start_bin << std::endl;
2483 
2484  // Number of elements
2485  nel=sb_face_element_pt.size();
2486 
2487  // Assume all elements have the same number of integration points
2488  unsigned nintpt_all=sb_face_element_pt[0]->integral_pt()->nweight();
2489 
2490  // Exploit symmetry during setup
2491  const bool exploit_symmetry=true;
2492 
2493  // Helper lookup scheme to exploit symmetry of interaction:
2494  // If integration point i_ed in element e_ed is illuminatED by
2495  // integration point i_ing in element e_ing (which is the
2496  // illuminatING one!) then the reverse is true too
2497  Vector<Vector<Vector<Vector<unsigned> > > > aux;
2498  if (exploit_symmetry)
2499  {
2500  nintpt_all=sb_face_element_pt[0]->integral_pt()->nweight();
2501  aux.resize(nel);
2502  for (unsigned e=0;e<nel;e++)
2503  {
2504  aux[e].resize(nintpt_all);
2505  for (unsigned ipt=0;ipt<nintpt_all;ipt++)
2506  {
2507  aux[e][ipt].resize(nel);
2508  }
2509  }
2510  }
2511 
2512  // Loop over all face elements -- viewed as illuminated ones
2513  for (unsigned e_illuminated=0;e_illuminated<nel;e_illuminated++)
2514  {
2515  StefanBoltzmannRadiationBase* illuminated_el_pt=
2516  dynamic_cast<StefanBoltzmannRadiationBase*>(
2517  sb_face_element_pt[e_illuminated]);
2518 
2519 #ifdef PARANOID
2520  if (illuminated_el_pt==0)
2521  {
2522  std::stringstream error_message;
2523  error_message << "Failed to cast illuminated element "
2524  << e_illuminated
2525  << " to StefanBoltzmannRadiationBase";
2526  throw OomphLibError(
2527  error_message.str(),
2530  }
2531 #endif
2532 
2533  // Recast to FaceElement
2534  FaceElement* illuminated_face_el_pt=
2535  dynamic_cast<FaceElement*>(illuminated_el_pt);
2536 
2537  // Loop over iluminated integration points
2538  unsigned nint=illuminated_el_pt->integral_pt()->nweight();
2539  for (unsigned ipt_illuminated=0;ipt_illuminated<nint;ipt_illuminated++)
2540  {
2541  // Local coordinate of integration point
2542  s_illuminated[0]=
2543  illuminated_el_pt->integral_pt()->knot(ipt_illuminated,0);
2544 
2545  // No recycling of shape fcts -- may as well call interpolated_x
2546  // directly
2547  illuminated_el_pt->interpolated_x(s_illuminated,r_illuminated);
2548 
2549  // Get outer unit normal
2550  illuminated_face_el_pt->outer_unit_normal(s_illuminated,
2551  unit_normal_illuminated);
2552 
2553  // Now loop over all other elements (the iluminating ones)
2554  // Note: this includes the current one because its integration
2555  // points may illuminate each other!
2556  unsigned e_lo=0;
2557  if (exploit_symmetry) e_lo=e_illuminated;
2558  for (unsigned e_illuminating=e_lo;e_illuminating<nel;e_illuminating++)
2559  {
2560  StefanBoltzmannRadiationBase* illuminating_el_pt=
2561  dynamic_cast<StefanBoltzmannRadiationBase*>(
2562  sb_face_element_pt[e_illuminating]);
2563 
2564 #ifdef PARANOID
2565  if (illuminating_el_pt==0)
2566  {
2567  std::stringstream error_message;
2568  error_message << "Failed to cast illuminating element "
2569  << e_illuminating
2570  << " to StefanBoltzmannRadiationBase";
2571  throw OomphLibError(
2572  error_message.str(),
2575  }
2576 #endif
2577 
2578  // Recast to FaceElement
2579  FaceElement* illuminating_face_el_pt=
2580  dynamic_cast<FaceElement*>(illuminating_el_pt);
2581 
2582  // Storage to accumulate indices of integration points in
2583  // illuminating face element that is visible from
2584  // current integration point
2585  Vector<unsigned> illuminating_integration_point_index;
2586 
2587  // Loop over iluminating integration points
2588  unsigned nint=illuminating_el_pt->integral_pt()->nweight();
2589  for (unsigned ipt_illuminating=0;ipt_illuminating<nint;
2590  ipt_illuminating++)
2591  {
2592  // Local coordinate of integration point
2593  s_illuminating[0]=
2594  illuminating_el_pt->integral_pt()->knot(ipt_illuminating,0);
2595 
2596  // No recycling of shape fcts -- may as well call interpolated_x
2597  // directly
2598  illuminating_el_pt->interpolated_x(s_illuminating,r_illuminating);
2599 
2600  // Get outer unit normal
2601  illuminating_face_el_pt->
2602  outer_unit_normal(s_illuminating,
2603  unit_normal_illuminating);
2604 
2605  // Get vector from illuminating point to illuminated point
2606  Vector<double> ray(2);
2607  ray[0]=r_illuminated[0]-r_illuminating[0];
2608  ray[1]=r_illuminated[1]-r_illuminating[1];
2609 
2610 
2611  Vector<Vector<double> > ray_vertex(2);
2612  ray_vertex[0].resize(2);
2613  ray_vertex[1].resize(2);
2614  ray_vertex[0][0]=r_illuminated[0];
2615  ray_vertex[0][1]=r_illuminated[1];
2616  ray_vertex[1][0]=r_illuminating[0];
2617  ray_vertex[1][1]=r_illuminating[1];
2618 
2619  // Do we radiate away from the positive face of the
2620  // illuminating point?
2621  double dot_illuminating=
2622  (unit_normal_illuminating[0]*ray[0]+
2623  unit_normal_illuminating[1]*ray[1]);
2624  if (dot_illuminating>0.0)
2625  {
2626 
2627  // Do we radiate onto from the positive face of the
2628  // illuminated point?
2629  double dot_illuminated=
2630  (unit_normal_illuminated[0]*ray[0]+
2631  unit_normal_illuminated[1]*ray[1]);
2632  if (dot_illuminated<0.0)
2633  {
2634 
2635  // Does the ray (a finite-length segment) from
2636  // radiating to radiated point intersect any other elements?
2637 
2638  // Vector of pairs of bin coordinates that
2639  // intersect ray
2640  Vector<std::pair<unsigned,unsigned> > intersected_bin;
2641  if (use_bins)
2642  {
2643  if (plot_it)
2644  {
2645  sprintf(filename,"RESLT/latest_ray.dat");
2646  some_file.open(filename);
2647  }
2648 
2649  // Find bins that are intersected by ray
2650  Vector<std::pair<unsigned,unsigned> > intersected_bin;
2651  bool populate_bin=false;
2652  FiniteElement* dummy_el_pt=0;
2653  bin_helper(ray_vertex,
2654  populate_bin,
2655  intersected_bin,
2656  dummy_el_pt,
2657  some_file);
2658 
2659  // End plot
2660  if (plot_it)
2661  {
2662  some_file.close();
2663  pause("done latest ray");
2664  }
2665 
2666  // Storage for vertices of possible intersection with ray
2667  Vector<Vector<double> > segment_vertex(2);
2668  segment_vertex[0].resize(2);
2669  segment_vertex[1].resize(2);
2670 
2671  // Search through all elements in bins along ray
2672  bool have_intersection=false;
2673  unsigned nbin=intersected_bin.size();
2674  for (unsigned b=0;b<nbin;b++)
2675  {
2676  // Get bin indices
2677  unsigned i=intersected_bin[b].first;
2678  unsigned j=intersected_bin[b].second;
2679 
2680  // Loop over elements in that bin
2681  for (std::set<FiniteElement*>::iterator it=
2682  Element_in_bin[i][j].begin();
2683  it!=Element_in_bin[i][j].end();it++)
2684  {
2685  // Get possibly blocking element
2686  StefanBoltzmannRadiationBase* el_pt=
2687  dynamic_cast<StefanBoltzmannRadiationBase*>(*it);
2688 
2689 #ifdef PARANOID
2690  if (illuminated_el_pt==0)
2691  {
2692  std::stringstream error_message;
2693  error_message
2694  << "Failed to cast possibly blocking element "
2695  << " to StefanBoltzmannRadiationBase";
2696  throw OomphLibError(
2697  error_message.str(),
2700  }
2701 #endif
2702  // Skip intersections with illuming/illuminated element
2703  if ((el_pt!=illuminated_el_pt)&&
2704  (el_pt!=illuminating_el_pt))
2705  {
2706  // Loop over sampling points along element, only
2707  // up to Nsample-1 because we're forming segment
2708  // with current and next sampling point.
2709  for (unsigned j_sample=0;j_sample<Nsample-1;j_sample++)
2710  {
2711  // Get cector of local coordinates of plot point j
2712  // as first vertex
2713  Vector<double> s(1);
2714  el_pt->get_s_plot(j_sample,Nsample,s);
2715 
2716  // Get coordinate of first vertex
2717  el_pt->interpolated_x(s,segment_vertex[0]);
2718 
2719  // Get cector of local coordinates of plot point j+1
2720  // as second vertex
2721  el_pt->get_s_plot(j_sample+1,Nsample,s);
2722 
2723  // Get coordinate of second vertex
2724  el_pt->interpolated_x(s,segment_vertex[1]);
2725 
2726  // Check intersection
2727  bool intersection=IntersectionChecker::intersects(
2728  segment_vertex,ray_vertex);
2729 
2730  // Bail out
2731  if (intersection)
2732  {
2733  have_intersection=true;
2734  break;
2735  }
2736  } // end of loop over sampling points
2737  } // endif for self-intersection
2738  if (have_intersection) break;
2739  } // end of loop over elements in bin
2740  if (have_intersection) break;
2741  }// End of loop over bins that contain ray
2742 
2743 
2744  // No intersection
2745  if (!have_intersection)
2746  {
2747  // Visible, so add integration point
2748  illuminating_integration_point_index.
2749  push_back(ipt_illuminating);
2750  }
2751  }
2752  // No bins: Brute force search loop
2753  else
2754  {
2755  // Intersection for star-shaped (non-convex) polygon
2756  // can only be detected in O(n^2) operations.
2757  Vector<Vector<double> > segment_vertex(2);
2758  segment_vertex[0].resize(2);
2759  segment_vertex[1].resize(2);
2760 
2761  // Loop over all segments to test for intersection
2762  bool have_intersection=false;
2763  for (unsigned e_intersect=0;e_intersect<nel;
2764  e_intersect++)
2765  {
2766 
2767  // Skip intersection with illuminating/ed elements
2768  if (! ( (e_intersect==e_illuminated) ||
2769  (e_intersect==e_illuminating) ) )
2770  {
2771 
2772  // Loop over sampling points along element
2773  for (unsigned j=0;j<Nsample-1;j++)
2774  {
2775  // Get cector of local coordinates of plot point j
2776  // as first vertex
2777  Vector<double> s(1);
2778  sb_face_element_pt[e_intersect]->
2779  get_s_plot(j,Nsample,s);
2780 
2781  // Get coordinate of first vertex
2782  sb_face_element_pt[e_intersect]->
2783  interpolated_x(s,segment_vertex[0]);
2784 
2785  // Get cector of local coordinates of plot point j+1
2786  // as second vertex
2787  sb_face_element_pt[e_intersect]->
2788  get_s_plot(j+1,Nsample,s);
2789 
2790  // Get coordinate of second vertex
2791  sb_face_element_pt[e_intersect]->
2792  interpolated_x(s,segment_vertex[1]);
2793 
2794  // Check intersection
2795  bool intersection=IntersectionChecker::intersects(
2796  segment_vertex,ray_vertex);
2797 
2798  if (intersection)
2799  {
2800  have_intersection=true;
2801  break;
2802  }
2803  }
2804  }
2805  if (have_intersection)
2806  {
2807  break;
2808  }
2809  }
2810 
2811  // No intersection
2812  if (!have_intersection)
2813  {
2814  // Visible, so add integration point
2815  illuminating_integration_point_index.
2816  push_back(ipt_illuminating);
2817  }
2818 
2819  } // end if for brute force (rather than bin-based) search loop
2820 
2821  }
2822  }
2823  }
2824 
2825  // Done all possibly illuminating integration points in
2826  // current possibly illuminating element
2827  unsigned npt=illuminating_integration_point_index.size();
2828  if (npt>0)
2829  {
2830  // Add info
2831  illuminated_el_pt->add_stefan_boltzmann_illumination_info(
2832  ipt_illuminated,illuminating_el_pt,
2833  illuminating_integration_point_index);
2834 
2835  // Set up reverse scheme
2836  if (exploit_symmetry)
2837  {
2838  for (unsigned i_ing=0;i_ing<npt;i_ing++)
2839  {
2840  aux[e_illuminating]
2841  [illuminating_integration_point_index[i_ing]]
2842  [e_illuminated].push_back(ipt_illuminated);
2843  }
2844  }
2845  }
2846  }
2847  }
2848  }
2849 
2850 
2851  // Now do other half of dependencies
2852  //----------------------------------
2853  if (exploit_symmetry)
2854  {
2855  // Loop over all face elements -- viewed as illuminated ones
2856  for (unsigned e_illuminated=0;e_illuminated<nel;e_illuminated++)
2857  {
2858  StefanBoltzmannRadiationBase* illuminated_el_pt=
2859  dynamic_cast<StefanBoltzmannRadiationBase*>(
2860  sb_face_element_pt[e_illuminated]);
2861 
2862 #ifdef PARANOID
2863  if (illuminated_el_pt==0)
2864  {
2865  std::stringstream error_message;
2866  error_message << "Failed to cast illuminated element "
2867  << e_illuminated
2868  << " to StefanBoltzmannRadiationBase";
2869  throw OomphLibError(
2870  error_message.str(),
2873  }
2874 #endif
2875 
2876  // Loop over iluminated integration points
2877  unsigned nint=illuminated_el_pt->integral_pt()->nweight();
2878  for (unsigned ipt_illuminated=0;ipt_illuminated<nint;ipt_illuminated++)
2879  {
2880  // Now loop over all other elements (the iluminating ones)
2881  for (unsigned e_illuminating=0;
2882  e_illuminating<e_illuminated;e_illuminating++)
2883  {
2884  StefanBoltzmannRadiationBase* illuminating_el_pt=
2885  dynamic_cast<StefanBoltzmannRadiationBase*>(
2886  sb_face_element_pt[e_illuminating]);
2887 
2888 #ifdef PARANOID
2889  if (illuminating_el_pt==0)
2890  {
2891  std::stringstream error_message;
2892  error_message << "Failed to cast illuminating element "
2893  << e_illuminating
2894  << " to StefanBoltzmannRadiationBase";
2895  throw OomphLibError(
2896  error_message.str(),
2899  }
2900 #endif
2901  // Get illuminating integration points
2902  Vector<unsigned> illuminating_integration_point_index=
2903  aux[e_illuminated][ipt_illuminated][e_illuminating];
2904  unsigned npt=illuminating_integration_point_index.size();
2905  if (npt>0)
2906  {
2907  // Add info
2908  illuminated_el_pt->add_stefan_boltzmann_illumination_info(
2909  ipt_illuminated,illuminating_el_pt,
2910  illuminating_integration_point_index);
2911  }
2912  }
2913  }
2914  }
2915  }
2916 
2917  double t_end=TimingHelpers::timer();
2918  oomph_info << "Time for setting up mutual Stefan Boltzmann radiation: "
2919  << t_end-t_start << std::endl;
2920  }
2921 
2922  }
Scalar * b
Definition: benchVecAdd.cpp:17
string filename
Definition: MergeRestartFiles.py:39
bool intersects(const Vector< Vector< double > > &first_segment_vertex, const Vector< Vector< double > > &second_segment_vertex, const double &epsilon_parallel=1.0e-15)
Definition: temporary_stefan_boltzmann_elements.h:57
void bin_helper(const Vector< Vector< double > > &ray_vertex, const bool &populate_bin, Vector< std::pair< unsigned, unsigned > > &intersected_bin, FiniteElement *el_pt, std::ofstream &outfile)
Definition: temporary_stefan_boltzmann_elements.h:1861
void pause(std::string message)
Pause and display message.
Definition: oomph_utilities.cc:1265
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
double timer
Definition: oomph_metis_from_parmetis_3.1.1/struct.h:210
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References oomph::StefanBoltzmannRadiationBase::add_stefan_boltzmann_illumination_info(), b, bin_helper(), Dx(), e(), Element_in_bin, MergeRestartFiles::filename, oomph::FiniteElement::get_s_plot(), i, oomph::FiniteElement::integral_pt(), oomph::FiniteElement::interpolated_x(), oomph::IntersectionChecker::intersects(), j, oomph::Integral::knot(), Max_coord(), Min_coord(), Nsample, oomph::Integral::nweight(), Nx_bin, Ny_bin, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, oomph::FaceElement::outer_unit_normal(), oomph::pause(), GlobalFct::plot_it(), s, oomph::TimingHelpers::timer(), and oomph::StefanBoltzmannRadiationBase::wipe_stefan_boltzmann_illumination_info().

Referenced by StefanBoltzmannProblem< ELEMENT >::setup_sb_radiation(), and StefanBoltzmannProblem< ELEMENT >::StefanBoltzmannProblem().

Variable Documentation

◆ Element_in_bin

Vector<Vector<std::set<FiniteElement*> > > oomph::StefanBoltzmannHelper::Element_in_bin

Bin to store pointers to finite elements in.

Referenced by bin_helper(), doc_bins(), and setup_stefan_boltzmann_visibility().

◆ Nsample

unsigned oomph::StefanBoltzmannHelper::Nsample =10

Number of sampling points in element to form segments with which we check intersection with ray

Referenced by doc_sample_points(), StefanBoltzmannProblem< ELEMENT >::setup_sb_radiation(), setup_stefan_boltzmann_visibility(), and StefanBoltzmannProblem< ELEMENT >::StefanBoltzmannProblem().

◆ Nx_bin

◆ Ny_bin