PetscErrorCode DMCoarsen_Cartesian(DM mesh, MPI_Comm comm, DM *coarseMesh) { ALE::Obj<ALE::CartesianMesh> oldMesh; PetscErrorCode ierr; PetscFunctionBegin; if (comm == MPI_COMM_NULL) comm = ((PetscObject)mesh)->comm; ierr = DMCartesianGetMesh(mesh, oldMesh); CHKERRQ(ierr); ierr = DMCartesianCreate(comm, coarseMesh); CHKERRQ(ierr); #if 0 ALE::Obj<ALE::Mesh> newMesh = ALE::Generator::refineMesh(oldMesh, refinementLimit, false); ierr = MeshCartesianSetMesh(*coarseMesh, newMesh); CHKERRQ(ierr); const ALE::Obj<ALE::CartesianMesh::real_section_type>& s = newMesh->getRealSection("default"); newMesh->setDiscretization(oldMesh->getDiscretization()); newMesh->setBoundaryCondition(oldMesh->getBoundaryCondition()); newMesh->setupField(s); #else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "Not yet implemented"); #endif PetscFunctionReturn(0); }
PetscErrorCode PETSCDM_DLLEXPORT MeshRefineSingularity_Fichera(ALE::Obj<ALE::Mesh> mesh, MPI_Comm comm, double * singularity, double factor, ALE::Obj<ALE::Mesh> * refinedMesh, PetscTruth interpolate = PETSC_FALSE) { ALE::Obj<ALE::Mesh> oldMesh = mesh; double oldLimit; PetscErrorCode ierr; PetscFunctionBegin; //ierr = MeshGetMesh(mesh, oldMesh);CHKERRQ(ierr); //ierr = MeshCreate(comm, refinedMesh);CHKERRQ(ierr); int dim = oldMesh->getDimension(); oldLimit = oldMesh->getMaxVolume(); //double oldLimInv = 1./oldLimit; double curLimit, tmpLimit; double minLimit = oldLimit/16384.; //arbitrary; const ALE::Obj<ALE::Mesh::real_section_type>& coordinates = oldMesh->getRealSection("coordinates"); const ALE::Obj<ALE::Mesh::real_section_type>& volume_limits = oldMesh->getRealSection("volume_limits"); volume_limits->setFiberDimension(oldMesh->heightStratum(0), 1); oldMesh->allocate(volume_limits); const ALE::Obj<ALE::Mesh::label_sequence>& cells = oldMesh->heightStratum(0); ALE::Mesh::label_sequence::iterator c_iter = cells->begin(); ALE::Mesh::label_sequence::iterator c_iter_end = cells->end(); double centerCoords[dim]; while (c_iter != c_iter_end) { const double * coords = oldMesh->restrictClosure(coordinates, *c_iter); for (int i = 0; i < dim; i++) { centerCoords[i] = 0; for (int j = 0; j < dim+1; j++) { centerCoords[i] += coords[j*dim+i]; } centerCoords[i] = centerCoords[i]/(dim+1); //PetscPrintf(oldMesh->comm(), "%f, ", centerCoords[i]); } //PetscPrintf(oldMesh->comm(), "\n"); double dist = 0.; double cornerdist = 0.; //HERE'S THE DIFFERENCE: if centercoords is less than the singularity coordinate for each direction, include that direction in the distance /* for (int i = 0; i < dim; i++) { if (centerCoords[i] <= singularity[i]) { dist += (centerCoords[i] - singularity[i])*(centerCoords[i] - singularity[i]); } } */ //determine: the per-dimension distance: cases if (dim > 2) { for (int i = 0; i < dim; i++) { cornerdist = 0.; if (centerCoords[i] > singularity[i]) { for (int j = 0; j < dim; j++) { if (j != i) cornerdist += (centerCoords[j] - singularity[j])*(centerCoords[j] - singularity[j]); } if (cornerdist < dist || dist == 0.) dist = cornerdist; } } } //patch up AROUND the corner by minimizing between the distance from the relevant axis and the singular vertex double singdist = 0.; for (int i = 0; i < dim; i++) { singdist += (centerCoords[i] - singularity[i])*(centerCoords[i] - singularity[i]); } if (singdist < dist || dist == 0.) dist = singdist; if (dist > 0.) { dist = sqrt(dist); double mu = pow(dist, factor); //PetscPrintf(oldMesh->comm(), "%f, %f\n", mu, dist); tmpLimit = oldLimit*pow(mu, dim); if (tmpLimit > minLimit) { curLimit = tmpLimit; } else curLimit = minLimit; } else curLimit = minLimit; //PetscPrintf(oldMesh->comm(), "%f, %f\n", dist, tmpLimit); volume_limits->updatePoint(*c_iter, &curLimit); c_iter++; } ALE::Obj<ALE::Mesh> newMesh = ALE::Generator::refineMesh(oldMesh, volume_limits, interpolate); //ierr = MeshSetMesh(*refinedMesh, newMesh);CHKERRQ(ierr); *refinedMesh = newMesh; const ALE::Obj<ALE::Mesh::real_section_type>& s = newMesh->getRealSection("default"); const Obj<std::set<std::string> >& discs = oldMesh->getDiscretizations(); for(std::set<std::string>::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter) { newMesh->setDiscretization(*f_iter, oldMesh->getDiscretization(*f_iter)); } newMesh->setupField(s); // PetscPrintf(newMesh->comm(), "refined\n"); PetscFunctionReturn(0); }