xolotl/solver/src/monitor/Monitor3D.cpp
/**
 * This is a monitoring method that will save 2D plots of the concentration of
 * a specific cluster at each grid point on the XZ surface, integrating over Y.
 */
This is a monitoring method that will save 2D plots of the concentration of
a specific cluster at each grid point on the XZ surface, integrating over Y.
This is a monitoring method that will save 2D plots of the concentration of a specific cluster at each grid point on the XZ surface integrating over Y .
PetscErrorCode
monitorSurfaceXZ3D(
	TS ts, PetscInt timestep, PetscReal time, Vec solution, void*)
{
	PetscErrorCode ierr;
	const double ****solutionArray, *gridPointSolution;
	IdType xs, xm, Mx, ys, ym, My, zs, zm, Mz;
	double x, z;
	PetscFunctionBeginUser;
	if (timestep % 10 != 0)
		PetscFunctionReturn(0);
	auto xolotlComm = util::getMPIComm();
	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 grid = solverHandler.getXGrid();
	double hz = solverHandler.getStepSizeZ();
	IdType iCluster = 0;
	auto myPoints =
		std::make_shared<std::vector<viz::dataprovider::DataPoint>>();
	viz::dataprovider::DataPoint thePoint;
	for (auto k = 0; k < Mz; k++) {
		z = (double)k * hz;
		for (auto i = 0; i < Mx; i++) {
			x = (grid[i] + grid[i + 1]) / 2.0 - grid[1];
			double conc = 0.0;
			for (auto j = 0; j < My; j++) {
				if (i >= xs && i < xs + xm && j >= ys && j < ys + ym &&
					k >= zs && k < zs + zm) {
					gridPointSolution = solutionArray[k][j][i];
					conc += gridPointSolution[iCluster];
				}
			} 
			double totalConc = 0.0;
			MPI_Reduce(
				&conc, &totalConc, 1, MPI_DOUBLE, MPI_SUM, 0, xolotlComm);
			if (procId == 0) {
				thePoint.value = totalConc;
				thePoint.t = time;
				thePoint.x = x;
				thePoint.y = z;
				myPoints->push_back(thePoint);
			}
		}
	}
	if (procId == 0) {
		surfacePlotXZ3D->getDataProvider()->setDataPoints(myPoints);
		std::stringstream title;
		title << "First Cluster";
		surfacePlotXZ3D->getDataProvider()->setDataName(title.str());
		title << " concentration";
		surfacePlotXZ3D->plotLabelProvider->titleLabel = title.str();
		std::stringstream timeLabel;
		timeLabel << "time: " << std::setprecision(4) << time << "s";
		surfacePlotXZ3D->plotLabelProvider->timeLabel = timeLabel.str();
		PetscReal currentTimeStep;
		ierr = TSGetTimeStep(ts, &currentTimeStep);
		CHKERRQ(ierr);
		std::stringstream timeStepLabel;
		timeStepLabel << "dt: " << std::setprecision(4) << currentTimeStep
					  << "s";
		surfacePlotXZ3D->plotLabelProvider->timeStepLabel = timeStepLabel.str();
		std::stringstream fileName;
		fileName << "surfaceXZ_TS" << timestep << ".png";
		surfacePlotXZ3D->write(fileName.str());
	}
	ierr = DMDAVecRestoreArrayDOFRead(da, solution, &solutionArray);
	CHKERRQ(ierr);
	PetscFunctionReturn(0);
}
PetscErrorCode monitorSurfaceXZ3D ( TS ts , PetscInt timestep , PetscReal time , Vec solution , void * ) { PetscErrorCode ierr ; const double * * * * solutionArray , * gridPointSolution ; IdType xs , xm , Mx , ys , ym , My , zs , zm , Mz ; double x , z ; PetscFunctionBeginUser ; if ( timestep % 10 != 0 ) PetscFunctionReturn ( 0 ) ; auto xolotlComm = util :: getMPIComm ( ) ; 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 grid = solverHandler . getXGrid ( ) ; double hz = solverHandler . getStepSizeZ ( ) ; IdType iCluster = 0 ; auto myPoints = std :: make_shared < std :: vector < viz :: dataprovider :: DataPoint > > ( ) ; viz :: dataprovider :: DataPoint thePoint ; for ( auto k = 0 ; k < Mz ; k ++ ) { z = ( double ) k * hz ; for ( auto i = 0 ; i < Mx ; i ++ ) { x = ( grid [ i ] + grid [ i + 1 ] ) / 2.0 - grid [ 1 ] ; double conc = 0.0 ; for ( auto j = 0 ; j < My ; j ++ ) { if ( i >= xs && i < xs + xm && j >= ys && j < ys + ym && k >= zs && k < zs + zm ) { gridPointSolution = solutionArray [ k ] [ j ] [ i ] ; conc += gridPointSolution [ iCluster ] ; } } double totalConc = 0.0 ; MPI_Reduce ( & conc , & totalConc , 1 , MPI_DOUBLE , MPI_SUM , 0 , xolotlComm ) ; if ( procId == 0 ) { thePoint . value = totalConc ; thePoint . t = time ; thePoint . x = x ; thePoint . y = z ; myPoints -> push_back ( thePoint ) ; } } } if ( procId == 0 ) { surfacePlotXZ3D -> getDataProvider ( ) -> setDataPoints ( myPoints ) ; std :: stringstream title ; title << " " ; surfacePlotXZ3D -> getDataProvider ( ) -> setDataName ( title . str ( ) ) ; title << " " ; surfacePlotXZ3D -> plotLabelProvider -> titleLabel = title . str ( ) ; std :: stringstream timeLabel ; timeLabel << " " << std :: setprecision ( 4 ) << time << " " ; surfacePlotXZ3D -> plotLabelProvider -> timeLabel = timeLabel . str ( ) ; PetscReal currentTimeStep ; ierr = TSGetTimeStep ( ts , & currentTimeStep ) ; CHKERRQ ( ierr ) ; std :: stringstream timeStepLabel ; timeStepLabel << " " << std :: setprecision ( 4 ) << currentTimeStep << " " ; surfacePlotXZ3D -> plotLabelProvider -> timeStepLabel = timeStepLabel . str ( ) ; std :: stringstream fileName ; fileName << " " << timestep << " " ; surfacePlotXZ3D -> write ( fileName . str ( ) ) ; } ierr = DMDAVecRestoreArrayDOFRead ( da , solution , & solutionArray ) ; CHKERRQ ( ierr ) ; PetscFunctionReturn ( 0 ) ; }
This is a monitoring method that will save 2D plots of the concentration of
 a specific cluster at each grid point on the XZ surface, integrating over Y.
This is a monitoring method that will save 2D plots of the concentration of a specific cluster at each grid point on the XZ surface integrating over Y .
// Initial declarations // Don't do anything if it is not on the stride // Gets the process ID // Get the da from ts // Get the solutionArray // Get the solver handler and local coordinates // Get the physical grid in the x direction // Setup step size variables // Choice of the cluster to be plotted // Create a DataPoint vector to store the data to give to the data provider // for the visualization // Create a point here so that it is not created and deleted in the loop // Loop on the full grid, Z and X first because they are the axis of the // plot // Compute z // Compute x // Initialize the value of the concentration to integrate over Y // If it is the locally owned part of the grid // Get the pointer to the beginning of the solution data for // this grid point // Integrate over Y // End of the loop on Y // Sum all the concentration on Y // If it is procId == 0 just store the integrated value in the // myPoints vector // Plot everything from procId == 0 // Get the data provider and give it the points // Change the title of the plot and the name of the data // Give the time to the label provider // Get the current time step // Give the timestep to the label provider // Render and save in file // Restore the solutionArray