예제 #1
0
파일: cartesian.c 프로젝트: Kun-Qu/petsc
PetscErrorCode DMView_Cartesian_Ascii(const ALE::Obj<ALE::CartesianMesh>& mesh, PetscViewer viewer)
{
    PetscViewerFormat format;
    PetscErrorCode    ierr;

    PetscFunctionBegin;
    ierr = PetscViewerGetFormat(viewer, &format);
    CHKERRQ(ierr);
    if (format == PETSC_VIEWER_ASCII_VTK) {
#if 0
        ierr = VTKViewer::writeHeader(viewer);
        CHKERRQ(ierr);
        ierr = VTKViewer::writeVertices(mesh, viewer);
        CHKERRQ(ierr);
        ierr = VTKViewer::writeElements(mesh, viewer);
        CHKERRQ(ierr);
#endif
    } else {
        int dim = mesh->getDimension();

        ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %d dimensions:\n", dim);
        CHKERRQ(ierr);
        /* FIX: Need to globalize */
        ierr = PetscViewerASCIIPrintf(viewer, "  %d vertices\n", mesh->getSieve()->getNumVertices());
        CHKERRQ(ierr);
        ierr = PetscViewerASCIIPrintf(viewer, "  %d cells\n",    mesh->getSieve()->getNumCells());
        CHKERRQ(ierr);
    }
    ierr = PetscViewerFlush(viewer);
    CHKERRQ(ierr);
    PetscFunctionReturn(0);
}
예제 #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);
}
예제 #3
0
파일: cartesian.c 프로젝트: Kun-Qu/petsc
PetscErrorCode DMCreateInterpolation_Cartesian(DM fineMesh, DM coarseMesh, Mat *interpolation, Vec *scaling)
{
    ALE::Obj<ALE::CartesianMesh> coarse;
    ALE::Obj<ALE::CartesianMesh> fine;
    Mat                          P;
    PetscErrorCode               ierr;

    PetscFunctionBegin;
    ierr = DMCartesianGetMesh(fineMesh,   fine);
    CHKERRQ(ierr);
    ierr = DMCartesianGetMesh(coarseMesh, coarse);
    CHKERRQ(ierr);
#if 0
    const ALE::Obj<ALE::Mesh::real_section_type>& coarseCoordinates = coarse->getRealSection("coordinates");
    const ALE::Obj<ALE::Mesh::real_section_type>& fineCoordinates   = fine->getRealSection("coordinates");
    const ALE::Obj<ALE::Mesh::label_sequence>&    vertices          = fine->depthStratum(0);
    const ALE::Obj<ALE::Mesh::real_section_type>& sCoarse           = coarse->getRealSection("default");
    const ALE::Obj<ALE::Mesh::real_section_type>& sFine             = fine->getRealSection("default");
    const ALE::Obj<ALE::Mesh::order_type>&        coarseOrder = coarse->getFactory()->getGlobalOrder(coarse, "default", sCoarse);
    const ALE::Obj<ALE::Mesh::order_type>&        fineOrder   = fine->getFactory()->getGlobalOrder(fine, "default", sFine);
    const int dim = coarse->getDimension();
    double *v0, *J, *invJ, detJ, *refCoords, *values;
#endif

    ierr = MatCreate(fine->comm(), &P);
    CHKERRQ(ierr);
#if 0
    ierr = MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
    CHKERRQ(ierr);
    ierr = MatSetFromOptions(P);
    CHKERRQ(ierr);
    ierr = PetscMalloc5(dim,double,&v0,dim*dim,double,&J,dim*dim,double,&invJ,dim,double,&refCoords,dim+1,double,&values);
    CHKERRQ(ierr);
    for(ALE::Mesh::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
        const ALE::Mesh::real_section_type::value_type *coords     = fineCoordinates->restrictPoint(*v_iter);
        const ALE::Mesh::point_type                     coarseCell = coarse->locatePoint(coords);

        coarse->computeElementGeometry(coarseCoordinates, coarseCell, v0, J, invJ, detJ);
        for(int d = 0; d < dim; ++d) {
            refCoords[d] = 0.0;
            for(int e = 0; e < dim; ++e) {
                refCoords[d] += invJ[d*dim+e]*(coords[e] - v0[e]);
            }
            refCoords[d] -= 1.0;
        }
        values[0] = 1.0/3.0 - (refCoords[0] + refCoords[1])/3.0;
        values[1] = 0.5*(refCoords[0] + 1.0);
        values[2] = 0.5*(refCoords[1] + 1.0);
        ierr = updateOperatorGeneral(P, fine, sFine, fineOrder, *v_iter, sCoarse, coarseOrder, coarseCell, values, INSERT_VALUES);
        CHKERRQ(ierr);
    }
    ierr = PetscFree5(v0,J,invJ,refCoords,values);
    CHKERRQ(ierr);
#endif
    ierr = MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    ierr = MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    *interpolation = P;
    PetscFunctionReturn(0);
}