예제 #1
0
파일: plexpoint.c 프로젝트: fengyuqi/petsc
PETSC_STATIC_INLINE PetscErrorCode DMPlexGetGlobalFieldOffset_Private(DM dm,PetscInt point,PetscInt field,PetscInt *offset)
{
  PetscFunctionBegin;
#if defined(PETSC_USE_DEBUG)
  {
    PetscErrorCode ierr;
    PetscInt       loff,lfoff,dof,cdof;
    ierr = PetscSectionGetOffset(dm->defaultGlobalSection,point,offset);CHKERRQ(ierr);
    ierr = PetscSectionGetOffset(dm->defaultSection,point,&loff);CHKERRQ(ierr);
    ierr = PetscSectionGetFieldOffset(dm->defaultSection,point,field,&lfoff);CHKERRQ(ierr);
    ierr = PetscSectionGetFieldDof(dm->defaultSection,point,field,&dof);CHKERRQ(ierr);
    ierr = PetscSectionGetFieldConstraintDof(dm->defaultSection,point,field,&cdof);CHKERRQ(ierr);
    *offset += lfoff - loff;
    if (dof-cdof <= 0) *offset = -1; /* Indicates no data */
  }
#else
  {
    PetscSection s  = dm->defaultSection;
    PetscSection fs = dm->defaultSection->field[field];
    PetscSection gs = dm->defaultGlobalSection;
    PetscInt     dof,cdof,loff,lfoff;
    loff    = s->atlasOff[point - s->pStart];
    lfoff   = fs->atlasOff[point - s->pStart];
    dof     = s->atlasDof[point - s->pStart];
    cdof    = s->bc ? s->bc->atlasDof[point - s->bc->pStart] : 0;
    *offset = gs->atlasOff[point - s->pStart] + lfoff - loff;
    if (dof-cdof <= 0) *offset = -1;
  }
#endif
  PetscFunctionReturn(0);
}
예제 #2
0
PetscErrorCode CreatePressureNullSpace(DM dm, AppCtx *user, MatNullSpace *nullSpace)
{
  Vec            vec, localVec;
  PetscErrorCode ierr;

  PetscFunctionBeginUser;
  ierr = DMGetGlobalVector(dm, &vec);CHKERRQ(ierr);
  ierr = DMGetLocalVector(dm, &localVec);CHKERRQ(ierr);
  ierr = VecSet(vec,  0.0);CHKERRQ(ierr);
  /* Put a constant in for all pressures
     Could change this to project the constant function onto the pressure space (when that is finished) */
  {
    PetscSection section;
    PetscInt     pStart, pEnd, p;
    PetscScalar  *a;

    ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
    ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
    ierr = VecGetArray(localVec, &a);CHKERRQ(ierr);
    for (p = pStart; p < pEnd; ++p) {
      PetscInt fDim, off, d;

      ierr = PetscSectionGetFieldDof(section, p, 1, &fDim);CHKERRQ(ierr);
      ierr = PetscSectionGetFieldOffset(section, p, 1, &off);CHKERRQ(ierr);
      for (d = 0; d < fDim; ++d) a[off+d] = 1.0;
    }
    ierr = VecRestoreArray(localVec, &a);CHKERRQ(ierr);
  }
  ierr = DMLocalToGlobalBegin(dm, localVec, INSERT_VALUES, vec);CHKERRQ(ierr);
  ierr = DMLocalToGlobalEnd(dm, localVec, INSERT_VALUES, vec);CHKERRQ(ierr);
  ierr = DMRestoreLocalVector(dm, &localVec);CHKERRQ(ierr);
  ierr = VecNormalize(vec, NULL);CHKERRQ(ierr);
  if (user->debug) {
    ierr = PetscPrintf(PetscObjectComm((PetscObject)dm), "Pressure Null Space\n");CHKERRQ(ierr);
    ierr = VecView(vec, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  }
  ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)dm), PETSC_FALSE, 1, &vec, nullSpace);CHKERRQ(ierr);
  ierr = DMRestoreGlobalVector(dm, &vec);CHKERRQ(ierr);
  /* New style for field null spaces */
  {
    PetscObject  pressure;
    MatNullSpace nullSpacePres;

    ierr = DMGetField(dm, 1, &pressure);CHKERRQ(ierr);
    ierr = MatNullSpaceCreate(PetscObjectComm(pressure), PETSC_TRUE, 0, NULL, &nullSpacePres);CHKERRQ(ierr);
    ierr = PetscObjectCompose(pressure, "nullspace", (PetscObject) nullSpacePres);CHKERRQ(ierr);
    ierr = MatNullSpaceDestroy(&nullSpacePres);CHKERRQ(ierr);
  }
  PetscFunctionReturn(0);
}
예제 #3
0
파일: plexpoint.c 프로젝트: fengyuqi/petsc
PETSC_STATIC_INLINE PetscErrorCode DMPlexGetLocalFieldOffset_Private(DM dm,PetscInt point,PetscInt field,PetscInt *offset)
{
  PetscFunctionBegin;
#if defined(PETSC_USE_DEBUG)
  {
    PetscErrorCode ierr;
    ierr = PetscSectionGetFieldOffset(dm->defaultSection,point,field,offset);CHKERRQ(ierr);
  }
#else
  {
    PetscSection s = dm->defaultSection->field[field];
    *offset = s->atlasOff[point - s->pStart];
  }
#endif
  PetscFunctionReturn(0);
}
예제 #4
0
void test(DM mesh) {
    const int dim = 2;
    const int field_count = 1;
    int components[field_count];
    int dof[field_count*(dim+1)];
    
    // Field 0 - temperature
    components[0]      =  1;
    dof[0*(dim+1) + 0] =  1; // vertices
    dof[0*(dim+1) + 1] =  0; // faces

    // Field 1 - pressure
    components[1]      =  1;
    dof[1*(dim+1) + 0] = 64; // vertices
    dof[1*(dim+1) + 1] =  0; // faces

    PetscSection section;
    DMPlexCreateSection(mesh,
                        dim,         // Spatial dimension
                        field_count, // Number of fields
                        components,  // Component count for each field
                        dof,         // DoF for each field component
                        0,           // Number of boundary conditions
                        NULL,        // BC Field
                        NULL,        // BC Points
                        &section);
    DMSetDefaultSection(mesh, section);

    // Temperature
    // Create a global vector
    Vec temperature = NULL;
    DMCreateGlobalVector(mesh, &temperature);

    // Get a temporary local vector & a pointer to its data
    Vec localTemp = NULL;
    DMGetLocalVector(mesh, &localTemp);
    PetscScalar * data = NULL;
    VecGetArray(localTemp, &data);

    // Loop over points in the section
    int start, end;
    DMGetDefaultSection(mesh, &section);
    PetscSectionGetChart(section, &start, &end);
    for (int point=start; point<end; ++point) {
        // Get the size & offset of field 0
        int dof, offset;
        PetscSectionGetFieldDof(section, point, 0, &dof);
        PetscSectionGetFieldOffset(section, point, 0, &offset); 

        // Set values
        for (int d=0; d<dof; ++d){
            data[offset+d] = point * 100 + d;            
        }
    }
    VecRestoreArray(localTemp, &data);

    // Broadcast values
    DMLocalToGlobalBegin(mesh, localTemp, INSERT_VALUES, temperature);
    DMLocalToGlobalEnd(mesh, localTemp, INSERT_VALUES, temperature);
    // Now each node should have all temperature values

    // Free the temp vector
    DMRestoreLocalVector(mesh,&localTemp);
}