Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

MatRad.cc

Go to the documentation of this file.
00001 /*
00002     File:           MatRad.cc
00003 
00004     Function:       See header file
00005 
00006     Author(s):      Andrew Willmott
00007 
00008     Copyright:      (c) 1997-2000, Andrew Willmott
00009 
00010     Notes:          
00011 
00012 */
00013 
00014 #include "MatRad.h"
00015 #include "cl/Timer.h"
00016 #include "gcl/Draw.h"
00017 #include <fstream.h>
00018 #include <stdio.h>
00019 
00020 Matd MatRad::EmissionVectors(PatchList &patches)
00021 {
00022     Matd    result(3, patches.NumItems());
00023     Int     i, j;
00024 
00025     for (i = 0; i < patches.NumItems(); i++)
00026         for (j = 0; j < 3; j++)
00027             result[j][i] = patches[i]->Emittance()[j];
00028         
00029     return(result);
00030 }
00031 
00032 SparseVecd MatRad::FormFactorToVector(Int j, PatchList &patches)
00033 // Find the vector of patch factors to patch j
00034 {
00035     const GCLReal   epsilon = 1e-6;
00036     SparseVecd      result(patches.NumItems());
00037     Int             i;
00038     GCLReal         vis;
00039     
00040 #ifdef RAD_VIS
00041     if (gRadControl->showRays && gRadControl->visibility == vis_1)
00042         display->Clear().Draw(GetScene());  
00043 #endif
00044     
00045     if (len(patches[j]->Reflectance()) <= 1e-6)
00046         result.MakeUnit(j);
00047     else
00048     {
00049         result.Begin();
00050         for (i = 0; i < patches.NumItems(); i++)
00051             if (i != j)
00052             {
00053                 vis = patches[i]->Visibility(patches[j]);
00054             
00055                 if (vis > 0.0)
00056                     result.AddElt(i, patches[i]->EstFormFactor(patches[j])
00057                                   * vis);
00058             }
00059         result.End();
00060     }
00061     
00062 #ifdef RAD_VIS
00063     if (gRadControl->showRays && gRadControl->visibility == vis_1)
00064     {
00065         display->Show();
00066         Pause();
00067     }
00068 #endif
00069     
00070     return(result);
00071 }
00072 
00073 Bool MatRad::Render()
00074 //  Returns true if no interruptions.
00075 {
00076     Int     i, j;
00077     Vec3d   error;
00078     Int     numPolys = patches.NumItems();
00079     Colour  c;
00080 
00081     RadMethod::Render();
00082     SparseVecd::SetFuzz(1e-10);
00083     
00084     SparseVecd FFRow(numPolys); // Row of form factors
00085             
00086     for (i = 0; i < 3; i++)
00087         A[i].SetSize(numPolys, numPolys);
00088     
00089     E.SetSize(3, numPolys);
00090     B.SetSize(3, numPolys);
00091 
00092     numPatches = 0;
00093 
00094     // Flat colour scene according to current reflectances
00095     ColourMeshInitial();
00096 
00097     if (Stage(1)) return(0);
00098     
00099     E = EmissionVectors(patches);
00100 
00101     if (Stage(2)) return(0);
00102 
00103     // Initialise A's to unit matrices
00104     for (j = 0; j < 3; j++)
00105         A[j] = vl_I;
00106 
00107     if (Stage(3)) return(0);
00108                                                                 
00109     // Calculate solution matrices
00110     for (i = 0; i < patches.NumItems(); i++)    
00111     {
00112         numPatches++;
00113         // find form factors to this patch
00114         FFRow = FormFactorToVector(i, patches); 
00115                 
00116         for (j = 0; j < 3; j++)
00117         {
00118             A[j][i] -= FFRow * patches[i]->Reflectance()[j];
00119             
00120             c[j] = patches[i]->Emittance()[j] + 
00121                 patches[i]->Reflectance()[j] * dot(FFRow, E[j]);
00122         }
00123         patches[i]->SetColour(c);
00124         
00125         if (Stage(4)) return(0);
00126     }
00127         
00128     if (Stage(5)) return(0);
00129     
00130     error = vl_1;
00131         
00132     while (len(error) > 0.001)
00133     {       
00134         if (!gRadControl->useConjGrad)
00135         {
00136             for (i = 0; i < 3; i++)         // Solve one more iteration
00137                 error[i] = SolveOverRelax(A[i], B[i], E[i], 1e-6,
00138                                           gRadControl->alpha);
00139         }
00140         else
00141             for (i = 0; i < 3; i++)         // Solve one more iteration
00142                 error[i] = SolveConjGrad(A[i], B[i], E[i], 1e-6);
00143             
00144         if (Stage(6)) return(0);
00145     }
00146 
00147     if (Stage(7)) return(0);
00148     
00149     return(1);
00150 }
00151 
00152 #ifdef RAD_VIS
00153 
00154 Void MatRad::DumpStats() {}
00155 
00156 Int MatRad::Stage(Int stage)
00157 {   
00158     Bool    animate = gRadControl->animate || gRadControl->pause;
00159     Int     i, j;
00160     Colour  c;
00161 
00162     switch (stage)
00163     {
00164     case 1:     // pre setup
00165         Field(out3) << patches.NumItems() << " patches."  << show;
00166         Field(out1) << "Forming emission vector E..." << show;
00167         break;
00168         
00169     case 2:     // post setup       
00170         Field(out1) << "Flat-colouring scene..." << show;
00171             
00172         for (i = 0; i < patches.NumItems(); i++)    // distribute colour
00173         {
00174             for (j = 0; j < 3; j++)
00175                 c[j] = patches[i]->Reflectance()[j] 
00176                     * Max((double) 0.2, E[j][i]);
00177                 
00178             patches[i]->SetColour(c);
00179         }
00180         
00181         ColourVertices();
00182         display->Redraw();      // draw
00183     
00184         Field(out1) << "1. Initialise F matrices..." << show;
00185         break;
00186         
00187     case 3:     
00188         Field(out1) << "2. Calculate F matrices..." << show;
00189         StartUpdate();
00190         break;
00191         
00192     case 4:     // After patch setup
00193         doUpdate = animate || Update();
00194 
00195         if (doUpdate)
00196         {
00197             if (gRadControl->animate && numPatches < patches.NumItems())
00198                 patches[numPatches]->SetHighlight(1);
00199             ColourVertices();
00200             display->Redraw();
00201             if (gRadControl->animate && numPatches < patches.NumItems())
00202                 patches[numPatches]->SetHighlight(0);
00203 
00204             RenderMatrix();
00205             Field(out3) << numPatches << " / " 
00206                         << patches.NumItems() << " patches."  << show;
00207 
00208             UpdateCont();
00209         }
00210         break;
00211         
00212     case 5:     // After FF calculation
00213         ColourVertices();
00214         display->Redraw();
00215         RenderMatrix();
00216         Field(out1) << "3. Solve equations..." << show;
00217         StartUpdate();
00218         solverIterations = 0;
00219         break;
00220         
00221     case 6:     // Middle of solve loop.
00222         solverIterations++;
00223         if (animate || Update())
00224         {
00225             // Colour scene according to current B vector
00226             for (i = 0; i < patches.NumItems(); i++)
00227             {
00228                 for (j = 0; j < 3; j++)
00229                     c[j] = B[j][i];
00230                     
00231                 patches[i]->SetColour(c);
00232             }
00233 
00234             ColourVertices();
00235             display->Redraw();  // Draw!
00236             Field(out3) << solverIterations << " iterations"  << show;
00237             UpdateCont();
00238         }
00239         break;
00240         
00241     case 7:
00242         ColourVertices();
00243         display->Redraw();
00244 
00245         Field(out3) << "Solving the matrix took " 
00246             << solverIterations << " iterations" << show;
00247         Field(out1) << "Finished!" << show;
00248         break;
00249     }
00250 
00251     if (Idle()) return(1);
00252     
00253     return(Pause());
00254 }
00255 
00256 #else
00257 
00258 Void MatRad::DumpMatrix()
00259 {
00260     Int     i, j, k;     
00261     Char    *rgb = "rgb";     
00262     String  temp;
00263     FILE    *file;       
00264     
00265     for (k = 0; k < 3; k++)
00266     {
00267         temp.Printf("%s.%c.mlab", gRadControl->outFile, rgb[k]);
00268         file = fopen(temp, "w");
00269         fprintf(file, "[\n");
00270         for (i = 0; i < A[k].Rows(); i++)
00271         {
00272             for (j = 0; j < A[k].Cols() - 1; j++)
00273                 fprintf(file, "%.18g, ", A[k][i][j]);
00274             fprintf(file, "%.18g\n", A[k][i][j]);
00275         }
00276         
00277         fprintf(file, "]\n");
00278         fclose(file);
00279     }
00280 
00281     temp.Printf("%s.stats", gRadControl->outFile);
00282     file = fopen(temp, "w");
00283     fprintf(file, "minArea    %.18g\n", stats.minArea);
00284     fprintf(file, "maxArea    %.18g\n", stats.maxArea);
00285     fprintf(file, "minRefl    [%.18g %.18g %.18g]\n",
00286         stats.minRefl[0], stats.minRefl[1], stats.minRefl[2]);
00287     fprintf(file, "maxRefl    [%.18g %.18g %.18g]\n",
00288         stats.maxRefl[0], stats.maxRefl[1], stats.maxRefl[2]);
00289     fclose(file);
00290 }
00291 
00292 Void MatRad::DumpStats()
00293 {
00294     GCLReal density, mem;
00295     Int i, j;
00296             
00297     density = 0;
00298     for (i = 0; i < 3; i++)
00299         for (j = 0; j < A[i].Rows(); j++)
00300             density += A[i][j].NumItems();
00301 
00302     mem = (density * (sizeof(GCLReal) + sizeof(Int))) + 
00303             sizeof(GCLReal) * E.Rows() * E.Cols() +
00304             sizeof(GCLReal) * B.Rows() * B.Cols();
00305     mem /= 1024.0;
00306     
00307     density /= 3 * A[0].Rows() * A[0].Cols();
00308     
00309     cout << dumpID
00310         << ' ' << totTime
00311         << ' ' << gRadControl->stage
00312         << ' ' << numPatches
00313         << ' ' << patches.NumItems()
00314         << ' ' << gRadControl->rays
00315         << ' ' << density
00316         << ' ' << mem
00317         << ' ' << grid->MemoryUsage()
00318         << ' ' << TotalMemoryUse()
00319         << endl;
00320 
00321     DumpScene();
00322 }
00323 
00324 Int MatRad::Stage(Int stage)
00325 {
00326     Colour c;
00327 
00328     if (CheckTime()) return(1);
00329     // CheckTime calls DumpStats if enough time has passed, and
00330     // also stops the clock.
00331 
00332     gRadControl->stage = stage;
00333 
00334     switch (stage)
00335     {
00336     case 1:     // pre setup
00337         cout << "method mat" << endl;
00338         if (!gRadControl->useConjGrad)
00339             cout << "solver overrelaxation" << endl;
00340         else
00341             cout << "solver conjugate-gradient" << endl;
00342 
00343         cout << "sub " << gRadControl->patchSubdivs << endl;
00344         cout << "alpha " << gRadControl->alpha << endl;
00345         cout << "scene " << sceneName << endl;
00346         cout << "polys " << gRadControl->numPolys << endl;
00347         cout << "format "
00348              << "ID "
00349              << "time "
00350              << "stage "
00351              << "procPatches "
00352              << "patches "
00353              << "rays "
00354              << "density " 
00355              << "mem "
00356              << "rtMem "
00357              << "rss "
00358              << endl; 
00359         cout << "----------------------------------------------------------" 
00360              << endl;
00361     
00362         DumpStats();
00363         break;
00364                 
00365     case 5:     // Finished calculating A[k]
00366         if (gRadControl->drawMatrix)
00367             DumpMatrix();
00368         break;
00369         
00370     case 6:     // Middle of solve loop.
00371 #ifndef RAD_BEST_TIMING
00372         Int     i, j;
00373 
00374         // Colour scene according to current B vector
00375         for (i = 0; i < patches.NumItems(); i++)
00376         {
00377             for (j = 0; j < 3; j++)
00378                 c[j] = B[j][i];
00379                 
00380             patches[i]->SetColour(c);
00381         }
00382 #endif
00383         break;
00384         
00385     case 7:
00386         DumpStats();
00387         break;
00388     }
00389 
00390     if (Idle()) return(0);
00391     timer.ContTimer();  
00392     return(0);
00393 }
00394 
00395 #endif
00396 
00397 Void MatRad::RemoveDirect()
00398 {
00399     Int     i;
00400 
00401 }
00402 
00403 Void MatRad::DrawMatrix(Renderer &r)
00404 {
00405 #ifdef RAD_VIS
00406     SVIterd     iter0, iter1, iter2;
00407 
00408     if (!gRadControl->drawMatrix || gRadControl->stop)
00409         return;
00410         
00411     Int         i, j, n;
00412     GCLReal     x1, x2, y1, y2, w;
00413         
00414     w = 2.0 / A[0].Cols();
00415     
00416     y1 = 1 - w;
00417     y2 = 1;
00418     n = Min(A[0].Rows(), (Int) numPatches);
00419 
00420     for (i = 0; i < n; i++)
00421     {
00422         x1 = -1;
00423         x2 = w - 1;
00424         
00425         iter0.Begin(A[0][i]);
00426         iter1.Begin(A[1][i]);
00427         iter2.Begin(A[2][i]);
00428 
00429         for (j = 0; j < A[0].Cols(); j++)
00430         {
00431             iter0.Inc(j);
00432             iter1.Inc(j);
00433             iter2.Inc(j);
00434 
00435             if (patches[i]->highlight == 2 && patches[j]->highlight == 3)
00436                 r.C(cPurple);
00437             else if (patches[i]->highlight == 2)
00438                 r.C(cYellow);
00439             else if (patches[j]->highlight == 3)
00440                 r.C(cGreen);
00441             else if (i == j)
00442                 r.C(cBlack);
00443             else    
00444             {
00445                 Colour mClr = cBlack;
00446                 
00447                 if (iter0.Exists(j)) mClr[0] = -iter0.Data();
00448                 if (iter1.Exists(j)) mClr[1] = -iter1.Data();
00449                 if (iter2.Exists(j)) mClr[2] = -iter2.Data();
00450 
00451                 r.C(A[0].Cols() * mClr);
00452             }
00453 
00454             PaintRect(r, Coord(x1, y1), Coord(x2, y2));
00455                 
00456             x1 += w;
00457             x2 += w;
00458         }
00459         
00460         y1 -= w;
00461         y2 -= w;
00462     }
00463 #endif
00464 }
00465 
00466 RadElem *MatRad::NewMesh()
00467 {
00468     return(new RadGrid());
00469 }

Generated at Sat Aug 5 00:26:52 2000 for Radiator by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000