Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
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);
}