/** * TODO: finish documentation * @return */ Fieldline Fieldline::reverseOrder() { std::vector<float> originalVectorValues = getData(); std::vector<Point3f> originalVectorPositions = getPositions(); Fieldline reversedLine; //reversedLine.reserve() int size = originalVectorValues.size(); for (int i = 0; i < size; i++) { Point3f point = originalVectorPositions[size - i - 1]; float value = originalVectorValues[size - i - 1]; reversedLine.insertPointData(point, value); } return reversedLine; }
Fieldline Fieldline::interpolate(int option, int Npoints) { // Field line will be interpolated to fixed number given by Npoints /* * If Npoints = 3, then the first and third interpolated points (and corresponding * data) will be set equal to the first and last points of the original field line, * and the second point will correspond to the "half-way" mark along the field line as * determined by the following weighting scheme * option=1: interpolate to fixed arc length * option=2: interpolate to fixed integral * option=3: interpolate to fixed index space */ Fieldline interpolated; int size = this->positions.size(); float n = 1; //initialize index for interpolated fieldline interpolated.insertPointData(positions[0], values[0]); interpolated.nearest.push_back(0); interpolated.tlocal.push_back(0); std::cout<<"interpolation option = "<< option<<"\n"; //First get the length of the field line. Total length should be the default. /* * TODO: Create an optional (public?) length variable. This would allow for * custom maxlength, useful for open fields. * * ts=totalLength/(Npoints-1) * |0 -------------------------|ts---------------------------Length| * |P0----P1----P2--...---a----|tlocal---b------...------------Pend| * |0-----t1----t2--...---ta------------tb------...------------tend| * */ float totalLength = 0; if(option==1) { totalLength = this->length[size-1]; std::cout<<"opt=1; total length = "<< totalLength << "\n"<<std::endl; } else if(option==2) { totalLength = this->integral[size-1]; std::cout<<"opt=2; integral tot: "<< totalLength << "\n"<<std::endl; } else if(option==3) { totalLength = size-1; std::cout<<"opt=3; points in original: "<< totalLength <<"\n" << std::endl; } else { std::cout<<"interpolation option not supported!"; } float ta = 0; // initialize ta,tb float tb = 0; int flinedex = 0; float ts = 0; while(n < Npoints-1) { ts = n/(Npoints-1); // ts in [0, 1.0) if (option == 1) { ta = length[flinedex]/totalLength; tb = length[flinedex+1]/totalLength; } else if (option == 2) { ta = integral[flinedex]/totalLength; tb = integral[flinedex+1]/totalLength; } else if (option == 3) { ta = flinedex; ta = ta/totalLength; tb = flinedex+1; tb = tb/totalLength; } else { std::cout<<"interpolation option not supported"; } if ((ts > ta)&&(ts <= tb)) // interpolating parameter between current and next points of original field line { float dt = tb-ta; // get size of parametric field line step float tloc = (ts-ta)/dt; // get local interpolation step (0,1) // linear interpolation float value = values[flinedex]*(1-tloc)+values[flinedex+1]*(tloc); //interpolate data Point3f point = getPositions()[flinedex]*(1-tloc)+getPositions()[flinedex+1]*tloc; //interpolate positions interpolated.insertPointData(point, value); interpolated.nearest.push_back(flinedex); //save closest point interpolated.tlocal.push_back(tloc); //save tlocal n = n+1.0; // std::cout<<"ta, tb, ts "<<ta<<", "<<tb<<" "<<ts<<" n = "<<n<<"\n"; } else { flinedex++; //interpolant not between current and next points of original field line, increment } } // End loop // Insert end positions, data, index, interpolating parameter interpolated.insertPointData(positions[size-1], values[size-1]); interpolated.nearest.push_back(size-1); interpolated.tlocal.push_back(1.0); return interpolated; }
int main (int argc, char * argv[]) { std::string filename; std::string variable; float c0; float c1; float c2; int iterations = 10; if (argc != 6) { cout << "integrator <filename> <variable> c0 c1 c2" << endl; exit(1); } filename = argv[1]; variable = argv[2]; c0 = boost::lexical_cast<float>(argv[3]); c1 = boost::lexical_cast<float>(argv[4]); c2 = boost::lexical_cast<float>(argv[5]); cout << "This program will compute the integral for a fieldline of the specified variable" << std::endl; Kameleon kameleon; //creates a kameleon object capable of working with any of the ccmc-supported models kameleon.open(filename); kameleon.loadVectorVariable("b"); //see the namespace ccmc::strings::variables for possible inputs kameleon.loadVectorVariable("e"); Tracer tracer(&kameleon); // Sets the interpolator (based on the kameleon object) to be used for tracing tracer.setMaxIterations(20000); //Maximum number of points in the fieldline tracer.setInnerBoundary(2.5f); //radius where fieldlines should stop (usually larger than the model's inner boundary) tracer.setDn(.2f); //step size relative to the cell size clock_t start, finish; cout << "Initializing field line\n"; Fieldline fieldline; /* * Supported tracers: input position is cartesian (x,y,z) unless the model is Enlil (r,theta,phi) * bidirectionalTrace(string variable, float p0, float p1, float p2) * bidirectionalTraceWithDipole(string variable, float p0, float p1, float p2) * unidirectionalTrace(string variable, float p0, float p1, float p2, Direction) where Direction must be keyword FORWARD or REVERSE * unidirectionalTraceWithDipole(string variable, float p0, float p1, float p2, Direction) */ cout << "Bidirectional trace beginning at ("<< c0 << ","<<c1<<","<<c2<<")"<<endl; start = clock(); fieldline = tracer.bidirectionalTrace("b",c0,c1,c2); finish = clock(); float elapsed_time = ((double) finish - (double) start) / CLOCKS_PER_SEC; cout << "Fieldline trace took "<< elapsed_time << " seconds\n"<<endl; cout << "After bidrectional trace\n"; cout << "Points in fieldline:"<<fieldline.size()<<endl; //You can retrieve the kameleon object's interpolator from the tracer, thusly: Interpolator * interpolator = tracer.interpolator; //interpolator will be deleted via the Tracer's destructor //Or you can make a new one, which is useful for doing interpolations in parallel: //Interpolator * interpolator = kameleon.createNewInterpolator(); //but make sure you delete it when done Fieldline fieldlineWithVariable; Point3f p, eField; float datum, pEx, pEy, pEz; for (int i = 0; i < fieldline.size(); i++) { p = fieldline.getPosition(i); datum = interpolator->interpolate(variable,p.component1,p.component2,p.component3); fieldlineWithVariable.insertPointData(p,datum); eField.component1 = interpolator->interpolate("ex",p.component1,p.component2,p.component3); eField.component2 = interpolator->interpolate("ey",p.component1,p.component2,p.component3); eField.component3 = interpolator->interpolate("ez",p.component1,p.component2,p.component3); fieldlineWithVariable.insertVectorData(eField); // eField in [mV/m] } vector<float> segmentLengths = fieldlineWithVariable.getDs(); //computes line segments of fieldline [Re] vector<float> integral = fieldlineWithVariable.integrate(); //sum of individual segmentLengths * variable vector<float> fieldlinePotential = fieldlineWithVariable.integrateVector(); // integral(E dot dl) std::cout<<"integral result:"<< integral.back()<< "[" << variable << "* Re]"<<endl; std::cout<<"Fieldline potential:"<< fieldlinePotential.back()*(6.3781e3)<<"[V]\n"; //[V] = [Re*mV/m]*[1V/1000mV]*[6.3781e6 m/Re] kameleon.close(); //delete interpolator; //required if you used kameleon.createNewInterpolator above std::cout << "finished" << std::endl; return 0; }