void Tracer_unidirectionalTrace(int id, const char * variable, const float * startComponent1, const float * startComponent2,
		const float * startComponent3, const int * step_max, const float * dn, int * actual_steps, float * x_array, float * y_array, float * z_array)
{
	ccmc::Tracer * tracer = tracerObjects[id];
	tracer->setMaxIterations(*step_max);
	if (dn < 0)
	{
		tracer->setDn(-*dn);
		Fieldline fieldline = tracer->unidirectionalTrace(variable, *startComponent1, *startComponent2, *startComponent3, ccmc::Tracer::REVERSE);
		*actual_steps = fieldline.size();
		for (int i = 0; i < fieldline.size(); i++)
		{
			x_array[i] = fieldline.getPositions()[i].component1;
			y_array[i] = fieldline.getPositions()[i].component2;
			z_array[i] = fieldline.getPositions()[i].component3;
		}
	}else
	{
		tracer->setDn(*dn);
		Fieldline fieldline = tracer->unidirectionalTrace(variable, *startComponent1, *startComponent2, *startComponent3, ccmc::Tracer::FOWARD);
		*actual_steps = fieldline.size();
		for (int i = 0; i < fieldline.size(); i++)
		{
			x_array[i] = fieldline.getPositions()[i].component1;
			y_array[i] = fieldline.getPositions()[i].component2;
			z_array[i] = fieldline.getPositions()[i].component3;
		}
	}

}
Exemple #2
0
	/**
	 * 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;
	}
Exemple #3
0
	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;
}