#include #include static char help[] = "Tests DMSwarm with DMShell\n\n"; #include #include #include #include #include #include #include #include #include #include #ifndef PETSC_SUCCESS #define PETSC_SUCCESS 0 #endif #define maxneigh 250 #define maxneigh10 1000 #define NumberDimensions 3 #define BufferLenght 4 #define occu_H_zero 5e-2 #define r_cutoff_ADP 6.2934034034 //! Angular dependant potential cutoff static double dmax_arg1, dmax_arg2; #define DMAX(a, b) \ (dmax_arg1 = (a), dmax_arg2 = (b), \ (dmax_arg1) > (dmax_arg2) ? (dmax_arg1) : (dmax_arg2)) double box_x_min = 0.0; double box_x_max = 0.0; double box_y_min = 0.0; double box_y_max = 0.0; double box_z_min = 0.0; double box_z_max = 0.0; PetscInt ndiv_mesh_X; PetscInt ndiv_mesh_Y; PetscInt ndiv_mesh_Z; double box_origin_0[3]; typedef struct DMD { /*! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @brief System information - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - !*/ //! @param n_atoms Number of atoms int n_atoms; //! @param Variable: with the atomistic data DM atomistic_data; //! @param Variable: with the background mesh DM background_mesh; //! @param Variable: with the bounding cell DM bounding_cell; /*! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @brief Interatomic potential information - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - !*/ //! @param r2_cutoff: Cutoff radius of the interatomic potential double r2_cutoff; } DMD; /*******************************************************/ typedef struct dump_file { /** @param n_atoms Number of atoms */ int n_atoms; /** @param specie: Integer which defines the atomic specie (H = 1 and Mg = 0) */ int *specie; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - System Lagrange multipliers - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /** @param beta: Thermodynamic Lagrange multiplier */ double *beta; /** @param gamma: Chemical Lagrange multiplier */ double *gamma; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Position-related variables - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /** @param mean_q: Mean value of each atomic position */ double *mean_q; /** @param stdv_q: Standard desviation of each atomic position */ double *stdv_q; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Chemical variables - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /** @param xi: Molar fraction (mean occupancy) */ double *xi; } dump_file; /*******************************************************/ dump_file read_dump_information(const char *SimulationFile) { unsigned int dim = NumberDimensions; dump_file Simulation; //! Variables to read atomistic data FILE *simulation_data = fopen(SimulationFile, "r"); char aux_line[10000]; int error; //! @brief Read the time step of the file int time_step; fgets(aux_line, sizeof(aux_line), simulation_data); error = fscanf(simulation_data, "%d\n", &time_step); //! @brief Read number of atomic position int n_atoms; fgets(aux_line, sizeof(aux_line), simulation_data); error = fscanf(simulation_data, "%d\n", &n_atoms); Simulation.n_atoms = n_atoms; //! @brief Read box bounds fgets(aux_line, sizeof(aux_line), simulation_data); error = fscanf(simulation_data, "%lf %lf\n", &box_x_min, &box_x_max); error = fscanf(simulation_data, "%lf %lf\n", &box_y_min, &box_y_max); error = fscanf(simulation_data, "%lf %lf\n", &box_z_min, &box_z_max); //! @brief Compute box-parameters box_origin_0[0] = box_x_min; box_origin_0[1] = box_y_min; box_origin_0[2] = box_z_min; //! @brief Create arrays Simulation.specie = (int *)calloc(n_atoms, sizeof(int)); Simulation.beta = (double *)calloc(n_atoms, sizeof(double)); Simulation.gamma = (double *)calloc(n_atoms, sizeof(double)); Simulation.mean_q = (double *)calloc(n_atoms * dim, sizeof(double)); Simulation.stdv_q = (double *)calloc(n_atoms, sizeof(double)); Simulation.xi = (double *)calloc(n_atoms, sizeof(double)); //! @brief Read properties from dump file fgets(aux_line, sizeof(aux_line), simulation_data); unsigned int Particle_Type; for (unsigned int i_site = 0; i_site < n_atoms; i_site++) { // clang-format off error = fscanf(simulation_data, "%i %lf %lf %lf %lf %lf %lf %lf\n", &(Particle_Type), &(Simulation.mean_q[3 * i_site + 0]), &(Simulation.mean_q[3 * i_site + 1]), &(Simulation.mean_q[3 * i_site + 2]), &(Simulation.stdv_q[i_site]), &(Simulation.xi[i_site]), &(Simulation.gamma[i_site]), &(Simulation.beta[i_site])); // clang-format on // Initialize particle type. if (Particle_Type == 1) { Simulation.specie[i_site] = 0; //! Magnesium } else if (Particle_Type == 2) { Simulation.specie[i_site] = 1; //! Hydrogen } else { std::cout << "FAIL Particle_Type:" << i_site << std::endl; } } // Close file fclose(simulation_data); // Check Hx molar fraction double xi_i; double xi_min_Hx = occu_H_zero; double xi_max_Hx = 1.0 - occu_H_zero; for (unsigned int i_site = 0; i_site < n_atoms; i_site++) { if (Simulation.specie[i_site] == 1) { // Hydrogen xi_i = Simulation.xi[i_site]; Simulation.xi[i_site] = xi_i < xi_min_Hx ? xi_min_Hx : xi_i; Simulation.xi[i_site] = xi_i > xi_max_Hx ? xi_max_Hx : xi_i; } } return Simulation; } /*******************************************************/ PetscErrorCode _DMLocatePoints_DMDARegular_IS(DM dm, Vec pos, IS *iscell) { PetscInt p, n, bs, npoints, si, sj, sk, milocal, mjlocal, mklocal, mx, my, mz; DM background_mesh; PetscInt *cellidx; const PetscScalar *coor; PetscMPIInt rank; PetscFunctionBegin; PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); PetscCall(VecGetLocalSize(pos, &n)); PetscCall(VecGetBlockSize(pos, &bs)); npoints = n / bs; PetscCall(PetscMalloc1(npoints, &cellidx)); PetscCall(DMGetApplicationContext(dm, &background_mesh)); PetscCall(DMDAGetCorners(background_mesh, &si, &sj, &sk, &milocal, &mjlocal, &mklocal)); PetscCall(DMDAGetInfo(background_mesh, NULL, &mx, &my, &mz, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); double dx = (box_x_max - box_x_min) / ((PetscReal)mx - 1); double dy = (box_y_max - box_y_min) / ((PetscReal)my - 1); double dz = (box_z_max - box_z_min) / ((PetscReal)mz - 1); char name[PETSC_MAX_PATH_LEN]; PetscCall(PetscSNPrintf(name, PETSC_MAX_PATH_LEN - 1, "outputs/atoms-rank%d.csv", rank)); std::ofstream file_f; file_f.open(name, std::ios::trunc); file_f << "rank: " << rank << std::endl; file_f << "si: " << si << " , " << "milocal: " << milocal << std::endl; file_f << "sj: " << sj << " , " << "mjlocal: " << mjlocal << std::endl; file_f << "sk: " << sk << " , " << "mklocal: " << mklocal << std::endl; file_f << "npoints: " << npoints << std::endl; file_f << "p" << " , " << "Coord.x" << " , " << "Coord.y" << " , " << "Coord.z" << " , " << "cell_idx" << " , " << "mi" << " , " << "mj" << " , " << "mk" << std::endl; PetscCall(VecGetArrayRead(pos, &coor)); for (p = 0; p < npoints; p++) { PetscReal coorx, coory, coorz; PetscInt mi, mj, mk; coorx = PetscRealPart(coor[3 * p + 0]); coory = PetscRealPart(coor[3 * p + 1]); coorz = PetscRealPart(coor[3 * p + 2]); mi = (PetscInt)round((coorx - (box_x_min)) / dx); mj = (PetscInt)round((coory - (box_y_min)) / dy); mk = (PetscInt)round((coorz - (box_z_min)) / dz); cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND; if ((mk >= sk) && (mk < sk + mklocal)) { if ((mj >= sj) && (mj < sj + mjlocal)) { if ((mi >= si) && (mi < si + milocal)) cellidx[p] = (mi - si) + (mj - sj) * milocal + (mk - sk) * milocal * mklocal; } } // if (coorx < box_x_min) // cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND; // if (coorx > box_x_max) // cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND; // if (coory < box_y_min) // cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND; // if (coory > box_y_max) // cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND; // if (coorz < box_z_min) // cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND; // if (coorz > box_z_max) // cellidx[p] = DMLOCATEPOINT_POINT_NOT_FOUND; file_f << p << " , " << coorx << " , " << coory << " , " << coorz << " , " << cellidx[p] << " , " << mi << " , " << mj << " , " << mk << std::endl; } file_f.close(); return 1; PetscCall(VecRestoreArrayRead(pos, &coor)); PetscCall(ISCreateGeneral(PETSC_COMM_SELF, npoints, cellidx, PETSC_OWN_POINTER, iscell)); PetscFunctionReturn(PETSC_SUCCESS); } /*******************************************************/ PetscErrorCode DMLocatePoints_DMDARegular(DM dm, Vec pos, DMPointLocationType ltype, PetscSF cellSF) { IS iscell; PetscSFNode *cells; PetscInt p, bs, npoints, nfound; const PetscInt *boxCells; PetscFunctionBegin; PetscCall(_DMLocatePoints_DMDARegular_IS(dm, pos, &iscell)); PetscCall(VecGetLocalSize(pos, &npoints)); PetscCall(VecGetBlockSize(pos, &bs)); npoints = npoints / bs; PetscCall(PetscMalloc1(npoints, &cells)); PetscCall(ISGetIndices(iscell, &boxCells)); for (p = 0; p < npoints; p++) { cells[p].rank = 0; cells[p].index = DMLOCATEPOINT_POINT_NOT_FOUND; cells[p].index = boxCells[p]; std::cout << "site " << p << " is located in cell: " << boxCells[p] << std::endl; } PetscCall(ISRestoreIndices(iscell, &boxCells)); PetscCall(ISDestroy(&iscell)); nfound = npoints; PetscCall(PetscSFSetGraph(cellSF, npoints, nfound, NULL, PETSC_OWN_POINTER, cells, PETSC_OWN_POINTER)); PetscCall(ISDestroy(&iscell)); PetscFunctionReturn(PETSC_SUCCESS); } /*******************************************************/ PetscErrorCode DMGetNeighbors_DMDARegular(DM dm, PetscInt *nneighbors, const PetscMPIInt **neighbors) { DM background_mesh; PetscFunctionBegin; PetscCall(DMGetApplicationContext(dm, &background_mesh)); PetscCall(DMGetNeighbors(background_mesh, nneighbors, neighbors)); PetscFunctionReturn(PETSC_SUCCESS); } /*******************************************************/ PetscErrorCode ParaviewViewGP(DM atomistic_data, const char prefix[]) { char name_vtk[PETSC_MAX_PATH_LEN]; PetscFunctionBegin; PetscCall(PetscSNPrintf(name_vtk, PETSC_MAX_PATH_LEN - 1, "%s.xmf", prefix)); PetscCall(DMSwarmViewXDMF(atomistic_data, name_vtk)); PetscFunctionReturn(PETSC_SUCCESS); } /*******************************************************/ /* Create a DMShell and attach a regularly spaced DMDA for point location Override methods for point location */ PetscErrorCode init_DMD_simulation(DMD *Simulation, dump_file Simulation_file) { unsigned int dim = NumberDimensions; DM atomistic_data, bounding_cell, background_mesh; PetscMPIInt rank; PetscInt blocksize; //! Topological variables AO dump2petsc_mapping; //! PetscInt n_atoms_local; PetscInt n_atoms_global; PetscInt n_atoms = Simulation_file.n_atoms; //! IS beta_bcc; IS gamma_bcc; IS interstitial_sites; PetscFunctionBegin; PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); /* Create a regularly spaced DMDA */ PetscInt overlap = 1; PetscInt dof = 1; PetscCall(DMDACreate3d(PETSC_COMM_WORLD, //! DM_BOUNDARY_PERIODIC, //! DM_BOUNDARY_PERIODIC, //! DM_BOUNDARY_PERIODIC, //! DMDA_STENCIL_BOX, //! ndiv_mesh_X, ndiv_mesh_Y, ndiv_mesh_Z, //! PETSC_DETERMINE, PETSC_DETERMINE, PETSC_DETERMINE, //! dof, overlap, NULL, NULL, NULL, &background_mesh)); PetscCall(DMSetFromOptions(background_mesh)); PetscCall(DMSetUp(background_mesh)); PetscCall(DMDASetUniformCoordinates(background_mesh, box_x_min, //! box_x_max, //! box_y_min, //! box_y_max, //! box_z_min, //! box_z_max)); /* Create a DMShell for point location purposes */ PetscCall(DMShellCreate(PETSC_COMM_WORLD, &bounding_cell)); PetscCall(DMSetApplicationContext(bounding_cell, background_mesh)); bounding_cell->ops->locatepoints = DMLocatePoints_DMDARegular; bounding_cell->ops->getneighbors = DMGetNeighbors_DMDARegular; /* Create the swarm */ PetscCall(DMCreate(PETSC_COMM_WORLD, &atomistic_data)); PetscCall(DMSetType(atomistic_data, DMSWARM)); PetscCall(DMSetDimension(atomistic_data, dim)); PetscCall(PetscObjectSetName((PetscObject)atomistic_data, "Atoms")); PetscCall(DMSwarmSetType(atomistic_data, DMSWARM_PIC)); PetscCall(DMSwarmSetCellDM(atomistic_data, bounding_cell)); //! Site idx PetscCall( DMSwarmRegisterPetscDatatypeField(atomistic_data, "idx", 1, PETSC_INT)); //! MPI rank PetscCall(DMSwarmRegisterPetscDatatypeField(atomistic_data, "MPI-rank", 1, PETSC_INT)); //! Molar fraction: Xi := _0 PetscCall(DMSwarmRegisterPetscDatatypeField(atomistic_data, "molar-fraction", 1, PETSC_REAL)); //! Energy density: mf_rho := _0 PetscCall(DMSwarmRegisterPetscDatatypeField(atomistic_data, "mf-rho", 1, PETSC_REAL)); //! Thermal multiplier: Beta := 1/(kb * T) PetscCall( DMSwarmRegisterPetscDatatypeField(atomistic_data, "beta", 1, PETSC_REAL)); //! Chemical multiplier: Gamma PetscCall(DMSwarmRegisterPetscDatatypeField(atomistic_data, "gamma", 1, PETSC_REAL)); //! Standard desviation of the position: stdv-q PetscCall(DMSwarmRegisterPetscDatatypeField(atomistic_data, "stdv-q", 1, PETSC_REAL)); //! First Piola-Kirchoff stress tensor: FPK PetscCall( DMSwarmRegisterPetscDatatypeField(atomistic_data, "FPK", 9, PETSC_REAL)); //! Boundary condition idex PetscCall(DMSwarmRegisterPetscDatatypeField(atomistic_data, "idx-bcc-beta", 1, PETSC_INT)); PetscCall(DMSwarmRegisterPetscDatatypeField(atomistic_data, "idx-bcc-gamma", 1, PETSC_INT)); PetscCall(DMSwarmRegisterPetscDatatypeField(atomistic_data, "idx-bcc-fix", 1, PETSC_INT)); PetscCall(DMSwarmFinalizeFieldRegister(atomistic_data)); PetscCall(DMSwarmSetLocalSizes(atomistic_data, n_atoms, BufferLenght)); //! @brief Get the bounding box of the background mesh PetscReal local_domain_ll[3]; PetscReal local_domain_ur[3]; PetscCall( DMGetLocalBoundingBox(background_mesh, local_domain_ll, local_domain_ur)); //! Lower left coordinates of the brick PetscReal xI_lw, yI_lw, zI_lw; xI_lw = local_domain_ll[0]; yI_lw = local_domain_ll[1]; zI_lw = local_domain_ll[2]; //! Upper right coordinates of the brick PetscReal xI_up, yI_up, zI_up; xI_up = local_domain_ur[0]; yI_up = local_domain_ur[1]; zI_up = local_domain_ur[2]; //! PetscReal local_dx, local_dy, local_dz; local_dx = xI_up - xI_lw; local_dy = yI_up - yI_lw; local_dz = zI_up - zI_lw; //! @brief mean_q: Mean value of each atomic position double *mean_q_ptr; PetscCall(DMSwarmGetField(atomistic_data, DMSwarmPICField_coor, &blocksize, NULL, (void **)&mean_q_ptr)); //! @brief idx_ptr: Global index of each atomic position int *idx_ptr; PetscCall( DMSwarmGetField(atomistic_data, "idx", NULL, NULL, (void **)&idx_ptr)); //! @brief Loop in the elemnts of the background mesh and find atoms in the //! mesh n_atoms_local = 0; for (PetscInt site_i = 0; site_i < n_atoms; site_i++) { if ((Simulation_file.mean_q[site_i * dim + 0] >= xI_lw) && //! (Simulation_file.mean_q[site_i * dim + 0] < xI_up) && //! (Simulation_file.mean_q[site_i * dim + 1] >= yI_lw) && //! (Simulation_file.mean_q[site_i * dim + 1] < yI_up) && //! (Simulation_file.mean_q[site_i * dim + 2] >= zI_lw) && //! (Simulation_file.mean_q[site_i * dim + 2] < zI_up)) { idx_ptr[n_atoms_local] = site_i; mean_q_ptr[n_atoms_local * dim + 0] = Simulation_file.mean_q[site_i * dim + 0]; mean_q_ptr[n_atoms_local * dim + 1] = Simulation_file.mean_q[site_i * dim + 1]; mean_q_ptr[n_atoms_local * dim + 2] = Simulation_file.mean_q[site_i * dim + 2]; n_atoms_local++; } } PetscCall(DMSwarmRestoreField(atomistic_data, DMSwarmPICField_coor, &blocksize, NULL, (void **)&mean_q_ptr)); PetscCall(DMSwarmRestoreField(atomistic_data, "idx", NULL, NULL, (void **)&idx_ptr)); //! @brief Set local sizes PetscCall(DMSwarmSetLocalSizes(atomistic_data, n_atoms_local, BufferLenght)); //! @brief idx_ptr: index of the site PetscCall(DMSwarmGetField(atomistic_data, "idx", &blocksize, NULL, (void **)&idx_ptr)); //! @brief specie: Integer which defines MPI rank location PetscInt *site_mpi_rank; PetscCall(DMSwarmGetField(atomistic_data, "MPI-rank", &blocksize, NULL, (void **)&site_mpi_rank)); //! @brief stdv_q: Standard desviation of each atomic position double *stdv_q; PetscCall(DMSwarmGetField(atomistic_data, "stdv-q", &blocksize, NULL, (void **)&stdv_q)); //! @brief mf-rho: Meanfield energy density double *mf_rho; PetscCall(DMSwarmGetField(atomistic_data, "mf-rho", &blocksize, NULL, (void **)&mf_rho)); //! @brief xi: Molar fraction (mean occupancy) double *xi; PetscCall(DMSwarmGetField(atomistic_data, "molar-fraction", &blocksize, NULL, (void **)&xi)); //! @brief beta: Thermal Lagrange multiplier double *beta; PetscCall(DMSwarmGetField(atomistic_data, "beta", &blocksize, NULL, (void **)&beta)); //! @brief gamma: Chemical Lagrange multiplier double *gamma; PetscCall(DMSwarmGetField(atomistic_data, "gamma", &blocksize, NULL, (void **)&gamma)); //! @brief Pointers with the information of the boundary condition PetscInt *beta_bcc_ptr; PetscCall(DMSwarmGetField(atomistic_data, "idx-bcc-beta", &blocksize, NULL, (void **)&beta_bcc_ptr)); PetscInt *gamma_bcc_ptr; PetscCall(DMSwarmGetField(atomistic_data, "idx-bcc-gamma", &blocksize, NULL, (void **)&gamma_bcc_ptr)); //! @brief Pointer with the list of interstitial sites PetscInt *interstitial_ptr = (PetscInt *)calloc(n_atoms_local, sizeof(PetscInt)); //! Set information from the .dump file for (PetscInt local_site_i = 0; local_site_i < n_atoms_local; local_site_i++) { PetscInt site_i = idx_ptr[local_site_i]; site_mpi_rank[local_site_i] = (PetscInt)rank; stdv_q[local_site_i] = Simulation_file.stdv_q[site_i]; xi[local_site_i] = Simulation_file.xi[site_i]; mf_rho[local_site_i] = 0.0; beta[local_site_i] = Simulation_file.beta[site_i]; gamma[local_site_i] = Simulation_file.gamma[site_i]; } //! Create a context to relate petsc numbering and dump numbering IS dump_ordering; PetscCall(ISCreateGeneral(PETSC_COMM_WORLD, n_atoms_local, idx_ptr, PETSC_COPY_VALUES, &dump_ordering)); PetscCall(AOCreateBasicIS(dump_ordering, NULL, &dump2petsc_mapping)); PetscCall(ISDestroy(&dump_ordering)); //! Tunrn dump numbering of "idx", and //! "interstitial" variables into petsc numbering PetscCall(AOApplicationToPetsc(dump2petsc_mapping, n_atoms_local, idx_ptr)); PetscCall(AOApplicationToPetsc(dump2petsc_mapping, n_atoms_local, interstitial_ptr)); //! Structures with the list of interstitial sites PetscCall(ISCreateGeneral(PETSC_COMM_WORLD, n_atoms_local, interstitial_ptr, PETSC_COPY_VALUES, &interstitial_sites)); PetscCall(PetscObjectSetName((PetscObject)interstitial_sites, "interstitial-sites")); //! Remove negative index PetscCall(ISGeneralFilter(interstitial_sites, 0, n_atoms)); //! Restore particle fields PetscCall(DMSwarmRestoreField(atomistic_data, "idx", &blocksize, NULL, (void **)&idx_ptr)); PetscCall(DMSwarmRestoreField(atomistic_data, "MPI-rank", &blocksize, NULL, (void **)&site_mpi_rank)); PetscCall(DMSwarmRestoreField(atomistic_data, "stdv-q", &blocksize, NULL, (void **)&stdv_q)); PetscCall(DMSwarmRestoreField(atomistic_data, "mf-rho", &blocksize, NULL, (void **)&mf_rho)); PetscCall(DMSwarmRestoreField(atomistic_data, "molar-fraction", &blocksize, NULL, (void **)&xi)); PetscCall(DMSwarmRestoreField(atomistic_data, "beta", &blocksize, NULL, (void **)&beta)); PetscCall(DMSwarmRestoreField(atomistic_data, "gamma", &blocksize, NULL, (void **)&gamma)); PetscCall(DMSwarmRestoreField(atomistic_data, "idx-bcc-beta", &blocksize, NULL, (void **)&beta_bcc_ptr)); PetscCall(DMSwarmRestoreField(atomistic_data, "idx-bcc-gamma", &blocksize, NULL, (void **)&gamma_bcc_ptr)); free(interstitial_ptr); //! Check global size DMSwarmGetSize(atomistic_data, &n_atoms_global); if (n_atoms_global != Simulation_file.n_atoms) { PetscCall(PetscError( PETSC_COMM_WORLD, __LINE__, "init_DMD_simulation", __FILE__, PETSC_ERR_RETURN, PETSC_ERROR_INITIAL, "The global size (%i) of the DMSwarm does not match the input (%i) !", n_atoms_global, Simulation_file.n_atoms)); PetscFunctionReturn(PETSC_ERR_RETURN); } //! Generate output structure Simulation->atomistic_data = atomistic_data; Simulation->background_mesh = background_mesh; Simulation->bounding_cell = bounding_cell; PetscFunctionReturn(PETSC_SUCCESS); } /*******************************************************/ PetscErrorCode destroy_DMD_simulation(DMD *Simulation) { //! @brief Atomistic variables DMDestroy(&Simulation->atomistic_data); DMDestroy(&Simulation->background_mesh); DMDestroy(&Simulation->bounding_cell); PetscFunctionReturn(PETSC_SUCCESS); } /*******************************************************/ int main(int argc, char **argv) { PetscFunctionBeginUser; PetscCall(PetscInitialize(&argc, &argv, (char *)0, help)); // const char SimulationFile[10000] = "Mg-hcp-cube-x3-x3-x3.dump"; // const char SimulationFile[10000] = "Mg-hcp-cube-x5-x5-x5.dump"; const char SimulationFile[10000] = "Mg-hcp-cube-x17-x10-x10.dump"; // const char SimulationFile[10000] = "Mg-sphere-radius-20.dump"; // const char SimulationFile[10000] = "MgHx-hcp-hex-nanowire-D-40-A.dump"; dump_file Simulation_file = read_dump_information(SimulationFile); //! ndiv_mesh_X = 3; ndiv_mesh_Y = 3; ndiv_mesh_Z = 3; DMD Simulation; PetscCall(init_DMD_simulation(&Simulation, Simulation_file)); PetscCall(DMView(Simulation.atomistic_data, PETSC_VIEWER_STDOUT_WORLD)); /* Get outputs */ // PetscCall(DMView(Simulation.atomistic_data, PETSC_VIEWER_STDOUT_WORLD)); // PetscCall(DMView(Simulation.background_mesh, PETSC_VIEWER_STDOUT_WORLD)); // PetscCall(DMView(Simulation.bounding_cell, PETSC_VIEWER_STDOUT_WORLD)); PetscCall(ParaviewViewGP(Simulation.atomistic_data, "outputs/atoms")); // Export the mesh to VTK format (VTU) Vec mesh_coors; DMGetCoordinates(Simulation.background_mesh, &mesh_coors); PetscViewer viewer; PetscViewerVTKOpen(PETSC_COMM_WORLD, "outputs/mesh.vts", FILE_MODE_WRITE, &viewer); VecView(mesh_coors, viewer); PetscViewerDestroy(&viewer); /* Free data */ PetscCall(destroy_DMD_simulation(&Simulation)); PetscCall(PetscFinalize()); return 0; } /*TEST build: requires: double !complex test: filter: grep -v atomic filter_output: grep -v atomic TEST*/