xolotl/solver/src/monitor/Monitor1D.cpp
/**
 * This is a monitoring method that will save 1D plots of many concentrations
 */
This is a monitoring method that will save 1D plots of many concentrations
This is a monitoring method that will save 1D plots of many concentrations
PetscErrorCode
monitorSeries1D(TS ts, PetscInt timestep, PetscReal time, Vec solution, void*)
{
	perf::ScopedTimer myTimer(seriesTimer);
	PetscErrorCode ierr;
	const double **solutionArray, *gridPointSolution;
	IdType xs, xm, Mx, ys, ym, My, zs, zm, Mz;
	double x = 0.0;
	PetscFunctionBeginUser;
	if (timestep % 10 != 0)
		PetscFunctionReturn(0);
	auto xolotlComm = util::getMPIComm();
	int worldSize;
	MPI_Comm_size(xolotlComm, &worldSize);
	int procId;
	MPI_Comm_rank(xolotlComm, &procId);
	DM da;
	ierr = TSGetDM(ts, &da);
	CHKERRQ(ierr);
	ierr = DMDAVecGetArrayDOFRead(da, solution, &solutionArray);
	CHKERRQ(ierr);
	auto& solverHandler = PetscSolver::getSolverHandler();
	solverHandler.getLocalCoordinates(xs, xm, Mx, ys, ym, My, zs, zm, Mz);
	auto& network = solverHandler.getNetwork();
	const auto networkSize = network.getNumClusters();
	auto grid = solverHandler.getXGrid();
	const auto loopSize = std::min(18, (int)networkSize);
	if (procId == 0) {
		std::vector<std::vector<viz::dataprovider::DataPoint>> myPoints(
			loopSize);
		for (auto xi = xs; xi < xs + xm; xi++) {
			gridPointSolution = solutionArray[xi];
			for (auto i = 0; i < loopSize; i++) {
				viz::dataprovider::DataPoint aPoint;
				aPoint.value = gridPointSolution[i];
				aPoint.t = time;
				aPoint.x = (grid[xi] + grid[xi + 1]) / 2.0 - grid[1];
				myPoints[i].push_back(aPoint);
			}
		}
		for (auto i = 1; i < worldSize; i++) {
			int localSize = 0;
			MPI_Recv(
				&localSize, 1, MPI_INT, i, 20, xolotlComm, MPI_STATUS_IGNORE);
			for (auto k = 0; k < localSize; k++) {
				MPI_Recv(
					&x, 1, MPI_DOUBLE, i, 21, xolotlComm, MPI_STATUS_IGNORE);
				for (auto j = 0; j < loopSize; j++) {
					double conc = 0.0;
					MPI_Recv(&conc, 1, MPI_DOUBLE, i, 22, xolotlComm,
						MPI_STATUS_IGNORE);
					viz::dataprovider::DataPoint aPoint;
					aPoint.value = conc;
					aPoint.t = time;
					aPoint.x = x;
					myPoints[j].push_back(aPoint);
				}
			}
		}
		for (auto i = 0; i < loopSize; i++) {
			auto thePoints =
				std::make_shared<std::vector<viz::dataprovider::DataPoint>>(
					myPoints[i]);
			seriesPlot1D->getDataProvider(i)->setDataPoints(thePoints);
			seriesPlot1D->getDataProvider(i)->setDataName(std::to_string(i));
		}
		std::stringstream title;
		title << "Concentrations";
		seriesPlot1D->plotLabelProvider->titleLabel = title.str();
		std::stringstream timeLabel;
		timeLabel << "time: " << std::setprecision(4) << time << "s";
		seriesPlot1D->plotLabelProvider->timeLabel = timeLabel.str();
		PetscReal currentTimeStep;
		ierr = TSGetTimeStep(ts, &currentTimeStep);
		CHKERRQ(ierr);
		std::stringstream timeStepLabel;
		timeStepLabel << "dt: " << std::setprecision(4) << currentTimeStep
					  << "s";
		seriesPlot1D->plotLabelProvider->timeStepLabel = timeStepLabel.str();
		std::stringstream fileName;
		fileName << "log_series_TS" << timestep << ".ppm";
		seriesPlot1D->write(fileName.str());
	}
	else {
		MPI_Send(&xm, 1, MPI_DOUBLE, 0, 20, xolotlComm);
		for (auto xi = xs; xi < xs + xm; xi++) {
			x = (grid[xi] + grid[xi + 1]) / 2.0 - grid[1];
			gridPointSolution = solutionArray[xi];
			MPI_Send(&x, 1, MPI_DOUBLE, 0, 21, xolotlComm);
			for (auto i = 0; i < loopSize; i++) {
				MPI_Send(
					&gridPointSolution[i], 1, MPI_DOUBLE, 0, 22, xolotlComm);
			}
		}
	}
	ierr = DMDAVecRestoreArrayDOFRead(da, solution, &solutionArray);
	CHKERRQ(ierr);
	PetscFunctionReturn(0);
}
PetscErrorCode monitorSeries1D ( TS ts , PetscInt timestep , PetscReal time , Vec solution , void * ) { perf :: ScopedTimer myTimer ( seriesTimer ) ; PetscErrorCode ierr ; const double * * solutionArray , * gridPointSolution ; IdType xs , xm , Mx , ys , ym , My , zs , zm , Mz ; double x = 0.0 ; PetscFunctionBeginUser ; if ( timestep % 10 != 0 ) PetscFunctionReturn ( 0 ) ; auto xolotlComm = util :: getMPIComm ( ) ; int worldSize ; MPI_Comm_size ( xolotlComm , & worldSize ) ; int procId ; MPI_Comm_rank ( xolotlComm , & procId ) ; DM da ; ierr = TSGetDM ( ts , & da ) ; CHKERRQ ( ierr ) ; ierr = DMDAVecGetArrayDOFRead ( da , solution , & solutionArray ) ; CHKERRQ ( ierr ) ; auto & solverHandler = PetscSolver :: getSolverHandler ( ) ; solverHandler . getLocalCoordinates ( xs , xm , Mx , ys , ym , My , zs , zm , Mz ) ; auto & network = solverHandler . getNetwork ( ) ; const auto networkSize = network . getNumClusters ( ) ; auto grid = solverHandler . getXGrid ( ) ; const auto loopSize = std :: min ( 18 , ( int ) networkSize ) ; if ( procId == 0 ) { std :: vector < std :: vector < viz :: dataprovider :: DataPoint > > myPoints ( loopSize ) ; for ( auto xi = xs ; xi < xs + xm ; xi ++ ) { gridPointSolution = solutionArray [ xi ] ; for ( auto i = 0 ; i < loopSize ; i ++ ) { viz :: dataprovider :: DataPoint aPoint ; aPoint . value = gridPointSolution [ i ] ; aPoint . t = time ; aPoint . x = ( grid [ xi ] + grid [ xi + 1 ] ) / 2.0 - grid [ 1 ] ; myPoints [ i ] . push_back ( aPoint ) ; } } for ( auto i = 1 ; i < worldSize ; i ++ ) { int localSize = 0 ; MPI_Recv ( & localSize , 1 , MPI_INT , i , 20 , xolotlComm , MPI_STATUS_IGNORE ) ; for ( auto k = 0 ; k < localSize ; k ++ ) { MPI_Recv ( & x , 1 , MPI_DOUBLE , i , 21 , xolotlComm , MPI_STATUS_IGNORE ) ; for ( auto j = 0 ; j < loopSize ; j ++ ) { double conc = 0.0 ; MPI_Recv ( & conc , 1 , MPI_DOUBLE , i , 22 , xolotlComm , MPI_STATUS_IGNORE ) ; viz :: dataprovider :: DataPoint aPoint ; aPoint . value = conc ; aPoint . t = time ; aPoint . x = x ; myPoints [ j ] . push_back ( aPoint ) ; } } } for ( auto i = 0 ; i < loopSize ; i ++ ) { auto thePoints = std :: make_shared < std :: vector < viz :: dataprovider :: DataPoint > > ( myPoints [ i ] ) ; seriesPlot1D -> getDataProvider ( i ) -> setDataPoints ( thePoints ) ; seriesPlot1D -> getDataProvider ( i ) -> setDataName ( std :: to_string ( i ) ) ; } std :: stringstream title ; title << " " ; seriesPlot1D -> plotLabelProvider -> titleLabel = title . str ( ) ; std :: stringstream timeLabel ; timeLabel << " " << std :: setprecision ( 4 ) << time << " " ; seriesPlot1D -> plotLabelProvider -> timeLabel = timeLabel . str ( ) ; PetscReal currentTimeStep ; ierr = TSGetTimeStep ( ts , & currentTimeStep ) ; CHKERRQ ( ierr ) ; std :: stringstream timeStepLabel ; timeStepLabel << " " << std :: setprecision ( 4 ) << currentTimeStep << " " ; seriesPlot1D -> plotLabelProvider -> timeStepLabel = timeStepLabel . str ( ) ; std :: stringstream fileName ; fileName << " " << timestep << " " ; seriesPlot1D -> write ( fileName . str ( ) ) ; } else { MPI_Send ( & xm , 1 , MPI_DOUBLE , 0 , 20 , xolotlComm ) ; for ( auto xi = xs ; xi < xs + xm ; xi ++ ) { x = ( grid [ xi ] + grid [ xi + 1 ] ) / 2.0 - grid [ 1 ] ; gridPointSolution = solutionArray [ xi ] ; MPI_Send ( & x , 1 , MPI_DOUBLE , 0 , 21 , xolotlComm ) ; for ( auto i = 0 ; i < loopSize ; i ++ ) { MPI_Send ( & gridPointSolution [ i ] , 1 , MPI_DOUBLE , 0 , 22 , xolotlComm ) ; } } } ierr = DMDAVecRestoreArrayDOFRead ( da , solution , & solutionArray ) ; CHKERRQ ( ierr ) ; PetscFunctionReturn ( 0 ) ; }
This is a monitoring method that will save 1D plots of many concentrations
This is a monitoring method that will save 1D plots of many concentrations
// Initial declarations // Don't do anything if it is not on the stride // Get the number of processes // Gets the process ID (important when it is running in parallel) // Get the da from ts // Get the solutionArray // Get the solver handler and local coordinates // Get the network and its size // Get the physical grid // To plot a maximum of 18 clusters of the whole benchmark // Create a DataPoint vector to store the data to give to the data // provider for the visualization // Loop on the grid // Get the pointer to the beginning of the solution data for this // grid point // Create a DataPoint with the concentration[i] as the value // and add it to myPoints // Loop on the other processes // Get the size of the local grid of that process // Loop on their grid // Get the position // and the concentrations // Create a Point with the concentration[i] as the value // and add it to myPoints // Get the data provider and give it the points // TODO: get the name or comp of the cluster // Change the title of the plot // Give the time to the label provider // Get the current time step // Give the timestep to the label provider // Render and save in file // Send the value of the local grid size to the master process // Loop on the grid // Dump x // Get the pointer to the beginning of the solution data for this // grid point // Send the value of the local position to the master process // Send the value of the concentrations to the master process // Restore the solutionArray