LR-splines  0.5
MakeWaterfall.cpp
Go to the documentation of this file.
00001 
00002 #include "LRSpline/LRSplineVolume.h"
00003 #include "LRSpline/Element.h"
00004 #include "LRSpline/Profiler.h"
00005 #include "LRSpline/Basisfunction.h"
00006 #include <iostream>
00007 #include <fstream>
00008 #include <cstring>
00009 #include <cmath>
00010 
00011 using namespace LR;
00012 using namespace std;
00013 
00014 int main(int argc, char **argv) {
00015 #ifdef TIME_LRSPLINE
00016         Profiler prof(argv[0]);
00017 #endif
00018 
00019         // set default parameter values
00020         int p         = 3;
00021         int N         = 3;
00022         int m         = 1;
00023         int scheme    = 0;  
00024         double R      = 0.5;   // radius of refinement layer
00025         double eps    = 0.005; // layer width parameter
00026         string parameters(" parameters: \n" \
00027                           "   -p      <n> polynomial DEGREE (order-1) of the basis\n" \
00028                           "   -n      <n> number of iterations\n" \
00029                           "   -m      <n> knot multiplicity\n" \
00030                           "   -scheme <n> refinement scheme (0=FULLSPAN, 1=MINSPAN, 2=STRUCTURED)\n" \
00031                           "   -help    display (this) help information\n");
00032         
00033         // read input
00034         for(int i=1; i<argc; i++) {
00035                 if(strcmp(argv[i], "-p") == 0)
00036                         p = atoi(argv[++i]);
00037                 else if(strcmp(argv[i], "-scheme") == 0)
00038                         scheme = atoi(argv[++i]);
00039                 else if(strcmp(argv[i], "-n") == 0)
00040                         N = atoi(argv[++i]);
00041                 else if(strcmp(argv[i], "-m") == 0)
00042                         m = atoi(argv[++i]);
00043                 else if(strcmp(argv[i], "-help") == 0) {
00044                         cout << "usage: " << argv[0] << endl << parameters;
00045                         exit(0);
00046                 } else {
00047                         cout << "usage: " << argv[0] << endl << parameters;
00048                         exit(1);
00049                 }
00050         }
00051 
00052         // do some error testing on input
00053         if(m > p )
00054                 m = p;
00055         if(scheme > 2)
00056                 scheme = 2;
00057         if(scheme < 0)
00058                 scheme = 0;
00059 
00060         // setup refinement parameters
00061         enum refinementStrategy strat;
00062         if(scheme == 0)
00063                 strat = LR_FULLSPAN;
00064         else if(scheme == 1)
00065                 strat = LR_MINSPAN;
00066         else if(scheme == 2)
00067                 strat = LR_STRUCTURED_MESH;
00068 
00069         // create initial geometry and an empty value thing
00070         LRSplineVolume *lrGeom   = new LRSplineVolume(p+1,p+1, p+1,p+1, p+1,p+1);
00071         LRSplineVolume *lrValues = lrGeom->copy();
00072 
00073         // do a variational diminishing approximation on the LRSpline object
00074         HashSet_iterator<Basisfunction*> geom = lrGeom->basisBegin();
00075         lrValues->rebuildDimension(1);
00076         for(Basisfunction *b : lrValues->getAllBasisfunctions()) {
00077                 double x = (**geom).cp(0);
00078                 double y = (**geom).cp(1);
00079                 double z = (**geom).cp(2);
00080                 double r = sqrt(x*x + y*y + z*z);
00081                 *b->cp() = atan((r-0.5)/eps);
00082                 ++geom;
00083         }
00084 
00085         // make room for all iterations... geometries and field values
00086         vector<LRSplineVolume*> geometries;
00087         vector<LRSplineVolume*> values;
00088         geometries.push_back(lrGeom);
00089         values.push_back(lrValues);
00090 
00091 
00092         // for all iterations
00093         for(int n=0; n<N; n++) {
00094                 std::cout << "Starting iteration " << (n+1) << " / " << N <<  std::endl;
00095                 lrGeom = geometries.back()->copy();
00096                 lrGeom->setRefMultiplicity(m);
00097                 lrGeom->setRefStrat(strat);
00098                 lrGeom->generateIDs();
00099 
00100                 if(scheme < 2) {
00101                         // find all elements which intersect the solution layer
00102                         vector<int> indices;
00103                         int i=0;
00104                         for(Element *el : lrGeom->getAllElements()) {
00105                                 double x0 = el->getParmin(0);
00106                                 double y0 = el->getParmin(1);
00107                                 double z0 = el->getParmin(2);
00108                                 double x1 = el->getParmax(0);
00109                                 double y1 = el->getParmax(1);
00110                                 double z1 = el->getParmax(2);
00111                                 if(x0*x0 + y0*y0 + z0*z0 < R*R &&
00112                                    x1*x1 + y1*y1 + z1*z1 > R*R) {
00113                                         indices.push_back(el->getId());
00114                                 }
00115                                 i++;
00116                         }
00117 
00118                         // perform actual refinement
00119                         lrGeom->refineElement(indices);
00120                 } else {
00121                         // find all Bsplines which intersect the solution layer
00122                         vector<int> indices;
00123                         int i=0;
00124                         for(Basisfunction *b : lrGeom->getAllBasisfunctions()) {
00125                                 double x0 = (*b)[0][1];
00126                                 double y0 = (*b)[1][1];
00127                                 double z0 = (*b)[2][1];
00128                                 double x1 = (*b)[0][2];
00129                                 double y1 = (*b)[1][2];
00130                                 double z1 = (*b)[2][2];
00131                                 if(x0*x0 + y0*y0 + z0*z0 < R*R &&
00132                                    x1*x1 + y1*y1 + z1*z1 > R*R) {
00133                                         indices.push_back(b->getId());
00134                                 }
00135                                 i++;
00136                         }
00137                         // perform actual refinement
00138                         lrGeom->refineBasisFunction(indices);
00139                 }
00140 
00141                 // make a VDA approximation to the solution
00142                 lrValues = lrGeom->copy();
00143                 geom = lrGeom->basisBegin();
00144                 lrValues->rebuildDimension(1);
00145                 for(Basisfunction *b : lrValues->getAllBasisfunctions()) {
00146                         double x = (**geom).cp(0);
00147                         double y = (**geom).cp(1);
00148                         double z = (**geom).cp(2);
00149                         double r = sqrt(x*x + y*y + z*z);
00150                         *b->cp() = atan((r-0.5)/eps)  /  b->w();
00151                         ++geom;
00152                 }
00153 
00154                 // add to final storage
00155                 values.push_back(lrValues);
00156                 geometries.push_back(lrGeom);
00157         }
00158         
00159         
00160         // write results to file
00161         ofstream lrfile;
00162         lrfile.open("waterfall_geom.lr");
00163         lrfile << *geometries.back() << endl;
00164         lrfile.close();
00165         lrfile.open("waterfall_values.lr");
00166         lrfile << *values.back() << endl;
00167         lrfile.close();
00168         cout << "Written waterfall_geom.lr and waterfall_values.lr" << endl;
00169 }
00170