petscdmlibmesh.C File Reference

Go to the source code of this file.

Classes

struct  DM_libMesh
struct  token

Functions

PetscErrorCode DMLibMeshGetBlocks (DM dm, PetscInt *n, char ***blocknames)
PetscErrorCode DMLibMeshGetVariables (DM dm, PetscInt *n, char ***varnames)
PetscErrorCode DMLibMeshSetUpName_Private (DM dm)
PetscErrorCode DMLibMeshSetSystem (DM dm, NonlinearImplicitSystem &sys)
PetscErrorCode DMLibMeshGetSystem (DM dm, NonlinearImplicitSystem *&sys)
static PetscErrorCode DMCreateFieldDecomposition_libMesh (DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
static PetscErrorCode DMCreateDomainDecomposition_libMesh (DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
PetscErrorCode DMLibMeshCreateFieldDecompositionDM (DM dm, PetscInt dnumber, PetscInt *dsizes, char ***dvarlists, DM *ddm)
PetscErrorCode DMLibMeshCreateDomainDecompositionDM (DM dm, PetscInt dnumber, PetscInt *dsizes, char ***dblocklists, DM *ddm)
static PetscErrorCode DMLibMeshParseDecompositionDescriptor_Private (DM dm, const char *ddesc, PetscInt *dtype, PetscInt *dcount, PetscInt **dsizes, char ****dlists)
static PetscErrorCode DMCreateFieldDecompositionDM_libMesh (DM dm, const char *ddesc, DM *ddm)
static PetscErrorCode DMCreateDomainDecompositionDM_libMesh (DM dm, const char *ddesc, DM *ddm)
static PetscErrorCode DMFunction_libMesh (DM dm, Vec x, Vec r)
static PetscErrorCode DMJacobian_libMesh (DM dm, Vec x, Mat jac, Mat pc, MatStructure *msflag)
static PetscErrorCode DMVariableBounds_libMesh (DM dm, Vec xl, Vec xu)
static PetscErrorCode DMCreateGlobalVector_libMesh (DM dm, Vec *x)
static PetscErrorCode DMCreateMatrix_libMesh (DM dm, const MatType, Mat *A)
static PetscErrorCode DMView_libMesh (DM dm, PetscViewer viewer)
static PetscErrorCode DMSetUp_libMesh (DM dm)
static PetscErrorCode DMDestroy_libMesh (DM dm)
PetscErrorCode DMCreateLibMesh (MPI_Comm comm, NonlinearImplicitSystem &sys, DM *dm)
PetscErrorCode DMCreate_libMesh (DM dm)

Function Documentation

PetscErrorCode DMCreate_libMesh ( DM  dm  ) 

Definition at line 1059 of file petscdmlibmesh.C.

References DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DMCreateDomainDecomposition_libMesh(), DMCreateDomainDecompositionDM_libMesh(), DMCreateFieldDecomposition_libMesh(), DMCreateFieldDecompositionDM_libMesh(), DMCreateGlobalVector_libMesh(), DMCreateMatrix_libMesh(), DMDestroy_libMesh(), DMSetUp_libMesh(), DMView_libMesh(), PetscErrorCode, DM_libMesh::varids, and DM_libMesh::varnames.

01060 {
01061   PetscErrorCode ierr;
01062   DM_libMesh     *dlm;
01063 
01064   PetscFunctionBegin;
01065   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
01066   ierr = PetscNewLog(dm,DM_libMesh,&dlm);CHKERRQ(ierr);
01067   dm->data = dlm;
01068 
01069   dlm->varids     = new(std::map<std::string, unsigned int>);
01070   dlm->blockids   = new(std::map<std::string, unsigned int>);
01071   dlm->varnames   = new(std::map<unsigned int, std::string>);
01072   dlm->blocknames = new(std::map<unsigned int, std::string>);
01073   dlm->decomposition   = PETSC_NULL;
01074   dlm->decomposition_type  = DMLIBMESH_NO_DECOMPOSITION;
01075 
01076   dm->ops->createglobalvector = DMCreateGlobalVector_libMesh;
01077   dm->ops->createlocalvector  = 0; // DMCreateLocalVector_libMesh;
01078   dm->ops->getcoloring        = 0; // DMGetColoring_libMesh;
01079   dm->ops->creatematrix       = DMCreateMatrix_libMesh;
01080   dm->ops->createinterpolation= 0; // DMCreateInterpolation_libMesh;
01081 
01082   dm->ops->refine             = 0; // DMRefine_libMesh;
01083   dm->ops->coarsen            = 0; // DMCoarsen_libMesh;
01084   dm->ops->getinjection       = 0; // DMGetInjection_libMesh;
01085   dm->ops->getaggregates      = 0; // DMGetAggregates_libMesh;
01086   
01087   dm->ops->createfielddecompositiondm  = DMCreateFieldDecompositionDM_libMesh;
01088   dm->ops->createfielddecomposition    = DMCreateFieldDecomposition_libMesh;
01089   dm->ops->createdomaindecompositiondm = DMCreateDomainDecompositionDM_libMesh;
01090   dm->ops->createdomaindecomposition   = DMCreateDomainDecomposition_libMesh;
01091 
01092   dm->ops->destroy            = DMDestroy_libMesh;
01093   dm->ops->view               = DMView_libMesh;
01094   dm->ops->setfromoptions     = 0; // DMSetFromOptions_libMesh;
01095   dm->ops->setup              = DMSetUp_libMesh;
01096 
01097   PetscFunctionReturn(0);
01098 }

static PetscErrorCode DMCreateDomainDecomposition_libMesh ( DM  dm,
PetscInt len,
char ***  namelist,
IS **  innerislist,
IS **  outerislist,
DM **  dmlist 
) [static]

Definition at line 321 of file petscdmlibmesh.C.

References libMesh::MeshBase::active_local_subdomain_elements_begin(), libMesh::MeshBase::active_local_subdomain_elements_end(), DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DMLibMeshSetUpName_Private(), libMesh::DofMap::dof_indices(), DM_libMesh::embedding, DM_libMesh::embedding_type, end, libMesh::DofMap::end_dof(), libMesh::DofMap::first_dof(), libMesh::System::get_dof_map(), libMesh::System::get_mesh(), PETSC_OWN_POINTER, PetscErrorCode, DM_libMesh::sys, DM_libMesh::varids, and DM_libMesh::varnames.

Referenced by DMCreate_libMesh().

00322 {
00323   PetscFunctionBegin;
00324   PetscErrorCode ierr;
00325   DM_libMesh     *dlm = (DM_libMesh *)(dm->data);
00326   NonlinearImplicitSystem *sys = dlm->sys;
00327   IS emb;
00328   if(dlm->decomposition_type != DMLIBMESH_DOMAIN_DECOMPOSITION) PetscFunctionReturn(0);
00329   *len = dlm->decomposition->size();
00330   if(namelist)      {ierr = PetscMalloc(*len*sizeof(char*), namelist);  CHKERRQ(ierr);}
00331   if(innerislist)   {ierr = PetscMalloc(*len*sizeof(IS),    innerislist);    CHKERRQ(ierr);}
00332   if(outerislist)   *outerislist = PETSC_NULL; /* FIX: allow mesh-based overlap. */
00333   if(dmlist)        {ierr = PetscMalloc(*len*sizeof(DM),    dmlist);    CHKERRQ(ierr);}
00334   for(unsigned int d = 0; d < dlm->decomposition->size(); ++d) {
00335     std::set<unsigned int>               dindices;
00336     std::string                          dname;
00337     std::map<std::string, unsigned int>  dblockids;
00338     std::map<unsigned int,std::string>   dblocknames;
00339     unsigned int                         dbcount = 0;
00340     for(std::set<unsigned int>::const_iterator bit = (*dlm->decomposition)[d].begin(); bit != (*dlm->decomposition)[d].end(); ++bit){
00341       unsigned int b = *bit;
00342       std::string bname = (*dlm->blocknames)[b];
00343       dblockids.insert(std::pair<std::string, unsigned int>(bname,b));
00344       dblocknames.insert(std::pair<unsigned int,std::string>(b,bname));
00345       if(!dbcount) dname = bname;
00346       else   dname += "_" + bname;
00347       ++dbcount;
00348       if(!innerislist) continue;
00349       MeshBase::const_element_iterator       el     = sys->get_mesh().active_local_subdomain_elements_begin(b);
00350       const MeshBase::const_element_iterator end_el = sys->get_mesh().active_local_subdomain_elements_end(b);
00351       for ( ; el != end_el; ++el) {
00352         const Elem* elem = *el;
00353         std::vector<unsigned int> evindices;
00354         /* Iterate only over this DM's variables. */
00355         for(std::map<std::string, unsigned int>::const_iterator vit = dlm->varids->begin(); vit != dlm->varids->end(); ++vit) {
00356           unsigned int v = vit->second;
00357           // Get the degree of freedom indices for the given variable off the current element.  
00358           sys->get_dof_map().dof_indices(elem, evindices, v);
00359           for(unsigned int i = 0; i < evindices.size(); ++i) {
00360             unsigned int dof = evindices[i];
00361             if(dof >= sys->get_dof_map().first_dof() && dof < sys->get_dof_map().end_dof()) /* might want to use variable_first/last_local_dof instead */
00362               dindices.insert(dof);
00363           }
00364         }
00365       }
00366     }
00367     if(namelist) {
00368       ierr = PetscStrallocpy(dname.c_str(),(*namelist)+d);            CHKERRQ(ierr);
00369     }
00370     if(innerislist) {
00371       PetscInt *darray;
00372       IS dis;
00373       ierr = PetscMalloc(sizeof(PetscInt)*dindices.size(), &darray); CHKERRQ(ierr);
00374       unsigned int i = 0;
00375       for(std::set<unsigned int>::const_iterator it = dindices.begin(); it != dindices.end(); ++it) {
00376         darray[i] = *it;
00377         ++i;
00378       }
00379       ierr = ISCreateGeneral(((PetscObject)dm)->comm, dindices.size(),darray, PETSC_OWN_POINTER, &dis); CHKERRQ(ierr);
00380       if(dlm->embedding) {
00381         /* Create a relative embedding into the parent's index space. */
00382         ierr = ISMapFactorRight(dis,dlm->embedding, PETSC_TRUE, &emb); CHKERRQ(ierr);
00383         PetscInt elen, dlen;
00384         ierr = ISGetLocalSize(emb, &elen); CHKERRQ(ierr);
00385         ierr = ISGetLocalSize(dis, &dlen);  CHKERRQ(ierr);
00386         if(elen != dlen) SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "Failed to embed field %D", d);
00387         ierr = ISDestroy(&dis); CHKERRQ(ierr);
00388         dis = emb;
00389       }
00390       else {
00391         emb = dis;
00392       }
00393       if(innerislist) {
00394         ierr = PetscObjectReference((PetscObject)dis); CHKERRQ(ierr);
00395         (*innerislist)[d] = dis;
00396       }
00397       ierr = ISDestroy(&dis); CHKERRQ(ierr);
00398     }
00399     if(dmlist) {
00400       DM ddm;
00401       ierr = DMCreate(((PetscObject)dm)->comm, &ddm); CHKERRQ(ierr);
00402       ierr = DMSetType(ddm, DMLIBMESH);               CHKERRQ(ierr);
00403       DM_libMesh *ddlm = (DM_libMesh*)(ddm->data);
00404       ddlm->sys = dlm->sys;
00405       /* copy over the varids and varnames */
00406       *ddlm->varids    = *dlm->varids; 
00407       *ddlm->varnames  = *dlm->varnames; 
00408       /* set the blocks from the d-th part of the decomposition. */
00409       *ddlm->blockids    = dblockids;    
00410       *ddlm->blocknames  = dblocknames;    
00411       ierr = PetscObjectReference((PetscObject)emb); CHKERRQ(ierr);
00412       ddlm->embedding = emb;
00413       ddlm->embedding_type = DMLIBMESH_DOMAIN_EMBEDDING;
00414 
00415       ierr = DMLibMeshSetUpName_Private(ddm); CHKERRQ(ierr);
00416       ierr = DMSetFromOptions(ddm);           CHKERRQ(ierr);
00417       (*dmlist)[d] = ddm;
00418     }
00419   }
00420   PetscFunctionReturn(0);
00421 }

static PetscErrorCode DMCreateDomainDecompositionDM_libMesh ( DM  dm,
const char *  ddesc,
DM *  ddm 
) [static]

Definition at line 685 of file petscdmlibmesh.C.

References DMLibMeshCreateDomainDecompositionDM(), DMLibMeshParseDecompositionDescriptor_Private(), and PetscErrorCode.

Referenced by DMCreate_libMesh().

00686 {
00687   PetscFunctionBegin;
00688   PetscErrorCode ierr;
00689   PetscInt dtype, dcount, *dsizes;
00690   char ***dlists;
00691   PetscFunctionBegin;
00692   *ddm = PETSC_NULL;
00693   ierr = DMLibMeshParseDecompositionDescriptor_Private(dm,ddesc,&dtype,&dcount,&dsizes,&dlists); CHKERRQ(ierr);
00694   if(dtype == DMLIBMESH_DOMAIN_DECOMPOSITION) {
00695     ierr = DMLibMeshCreateDomainDecompositionDM(dm,dcount,dsizes,dlists,ddm); CHKERRQ(ierr);
00696   }
00697   else SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "Uexpected unknown decomposition type for domain decomposition descriptor %s", ddesc);
00698   PetscFunctionReturn(0);
00699 }

static PetscErrorCode DMCreateFieldDecomposition_libMesh ( DM  dm,
PetscInt len,
char ***  namelist,
IS **  islist,
DM **  dmlist 
) [static]

Definition at line 219 of file petscdmlibmesh.C.

References libMesh::MeshBase::active_local_subdomain_elements_begin(), libMesh::MeshBase::active_local_subdomain_elements_end(), DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DMLibMeshSetUpName_Private(), libMesh::DofMap::dof_indices(), DM_libMesh::embedding, DM_libMesh::embedding_type, end, libMesh::DofMap::end_dof(), libMesh::DofMap::first_dof(), libMesh::System::get_dof_map(), libMesh::System::get_mesh(), PETSC_OWN_POINTER, PetscErrorCode, DM_libMesh::sys, DM_libMesh::varids, and DM_libMesh::varnames.

Referenced by DMCreate_libMesh().

00220 {
00221   PetscFunctionBegin;
00222   PetscErrorCode ierr;
00223   DM_libMesh     *dlm = (DM_libMesh *)(dm->data);
00224   NonlinearImplicitSystem *sys = dlm->sys;
00225   IS emb;
00226   if(dlm->decomposition_type != DMLIBMESH_FIELD_DECOMPOSITION) PetscFunctionReturn(0);
00227 
00228   *len = dlm->decomposition->size();
00229   if(namelist) {ierr = PetscMalloc(*len*sizeof(char*), namelist);  CHKERRQ(ierr);}
00230   if(islist)   {ierr = PetscMalloc(*len*sizeof(IS),    islist);    CHKERRQ(ierr);}
00231   if(dmlist)   {ierr = PetscMalloc(*len*sizeof(DM),    dmlist);    CHKERRQ(ierr);}
00232   DofMap& dofmap = dlm->sys->get_dof_map();
00233   for(unsigned int d = 0; d < dlm->decomposition->size(); ++d) {
00234     std::set<unsigned int>               dindices;
00235     std::string                          dname;
00236     std::map<std::string, unsigned int>  dvarids;
00237     std::map<unsigned int, std::string>  dvarnames;
00238     unsigned int                         dvcount = 0;
00239     for(std::set<unsigned int>::const_iterator dvit = (*dlm->decomposition)[d].begin(); dvit != (*dlm->decomposition)[d].end(); ++dvit){
00240       unsigned int v = *dvit;
00241       std::string vname = (*dlm->varnames)[v];
00242       dvarids.insert(std::pair<std::string, unsigned int>(vname,v));
00243       dvarnames.insert(std::pair<unsigned int,std::string>(v,vname));
00244       if(!dvcount) dname = vname;
00245       else   dname += "_" + vname;
00246       ++dvcount;
00247       if(!islist) continue;
00248       /* Iterate only over this DM's blocks. */
00249       for(std::map<std::string, unsigned int>::const_iterator bit = dlm->blockids->begin(); bit != dlm->blockids->end(); ++bit) {
00250         unsigned int b = bit->second;
00251         MeshBase::const_element_iterator el     = sys->get_mesh().active_local_subdomain_elements_begin(b);
00252         MeshBase::const_element_iterator end_el = sys->get_mesh().active_local_subdomain_elements_end(b);
00253         for ( ; el != end_el; ++el) {
00254           const Elem* elem = *el;
00255           //unsigned int e_subdomain = elem->subdomain_id();
00256           std::vector<unsigned int> evindices;
00257           // Get the degree of freedom indices for the given variable off the current element.  
00258           dofmap.dof_indices(elem, evindices, v);
00259           for(unsigned int i = 0; i < evindices.size(); ++i) {
00260             unsigned int dof = evindices[i];
00261             if(dof >= dofmap.first_dof() && dof < dofmap.end_dof()) /* might want to use variable_first/last_local_dof instead */
00262               dindices.insert(dof);
00263           }
00264         }
00265       }
00266     }
00267     if(namelist) {
00268       ierr = PetscStrallocpy(dname.c_str(),(*namelist)+d);            CHKERRQ(ierr);
00269     }
00270     if(islist) {
00271       IS dis;
00272       PetscInt *darray;
00273       ierr = PetscMalloc(sizeof(PetscInt)*dindices.size(), &darray); CHKERRQ(ierr);
00274       unsigned int i = 0;
00275       for(std::set<unsigned int>::const_iterator it = dindices.begin(); it != dindices.end(); ++it) {
00276         darray[i] = *it;
00277         ++i;
00278       }
00279       ierr = ISCreateGeneral(((PetscObject)dm)->comm, dindices.size(),darray, PETSC_OWN_POINTER, &dis); CHKERRQ(ierr);
00280       if(dlm->embedding) {
00281         /* Create a relative embedding into the parent's index space. */
00282         ierr = ISMapFactorRight(dis,dlm->embedding, PETSC_TRUE, &emb); CHKERRQ(ierr);
00283         PetscInt elen, dlen;
00284         ierr = ISGetLocalSize(emb, &elen); CHKERRQ(ierr);
00285         ierr = ISGetLocalSize(dis, &dlen); CHKERRQ(ierr);
00286         if(elen != dlen) SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "Failed to embed subdomain %D", d);
00287         ierr = ISDestroy(&dis); CHKERRQ(ierr);
00288         dis = emb;
00289       }
00290       else {
00291         emb = dis;
00292       }
00293       (*islist)[d] = dis;
00294     }
00295     if(dmlist) {
00296       DM ddm;
00297       ierr = DMCreate(((PetscObject)dm)->comm, &ddm); CHKERRQ(ierr);
00298       ierr = DMSetType(ddm, DMLIBMESH);               CHKERRQ(ierr);
00299       DM_libMesh *ddlm = (DM_libMesh*)(ddm->data);
00300       ddlm->sys = dlm->sys;
00301       /* copy over the block ids and names */
00302       *ddlm->blockids = *dlm->blockids; 
00303       *ddlm->blocknames = *dlm->blocknames;
00304       /* set the vars from the d-th part of the decomposition. */
00305       *ddlm->varids     = dvarids;        
00306       *ddlm->varnames   = dvarnames;        
00307       ierr = PetscObjectReference((PetscObject)emb); CHKERRQ(ierr);
00308       ddlm->embedding = emb;
00309       ddlm->embedding_type = DMLIBMESH_FIELD_EMBEDDING;
00310 
00311       ierr = DMLibMeshSetUpName_Private(ddm); CHKERRQ(ierr);
00312       ierr = DMSetFromOptions(ddm);           CHKERRQ(ierr);
00313       (*dmlist)[d] = ddm;
00314     }
00315   }
00316   PetscFunctionReturn(0);
00317 }

static PetscErrorCode DMCreateFieldDecompositionDM_libMesh ( DM  dm,
const char *  ddesc,
DM *  ddm 
) [static]

Definition at line 667 of file petscdmlibmesh.C.

References DMLibMeshCreateFieldDecompositionDM(), DMLibMeshParseDecompositionDescriptor_Private(), and PetscErrorCode.

Referenced by DMCreate_libMesh().

00668 {
00669   PetscFunctionBegin;
00670   PetscErrorCode ierr;
00671   PetscInt dtype, dcount, *dsizes;
00672   char ***dlists;
00673   PetscFunctionBegin;
00674   *ddm = PETSC_NULL;
00675   ierr = DMLibMeshParseDecompositionDescriptor_Private(dm,ddesc,&dtype,&dcount,&dsizes,&dlists); CHKERRQ(ierr);
00676   if(dtype == DMLIBMESH_FIELD_DECOMPOSITION){ 
00677     ierr = DMLibMeshCreateFieldDecompositionDM(dm,dcount,dsizes,dlists,ddm); CHKERRQ(ierr);
00678   }
00679   else SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "Uexpected unknown decomposition type for field decomposition descriptor %s", ddesc);
00680   PetscFunctionReturn(0);
00681 }

static PetscErrorCode DMCreateGlobalVector_libMesh ( DM  dm,
Vec *  x 
) [static]

Definition at line 863 of file petscdmlibmesh.C.

References DM_libMesh::embedding, PetscBool, PetscErrorCode, libMesh::System::solution, DM_libMesh::sys, and libMesh::PetscVector< T >::vec().

Referenced by DMCreate_libMesh().

00864 {
00865   PetscFunctionBegin;
00866   PetscErrorCode ierr;
00867   DM_libMesh     *dlm = (DM_libMesh *)(dm->data);
00868   PetscBool eq;
00869 
00870   ierr = PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH, &eq); CHKERRQ(ierr);
00871 
00872   if (!eq)
00873     SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "DM of type %s, not of type %s", ((PetscObject)dm)->type, DMLIBMESH);
00874 
00875   if (!dlm->sys)
00876     SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No libMesh system set for DM_libMesh");
00877 
00878   NumericVector<Number>* nv = (dlm->sys->solution).get();
00879   PetscVector<Number>*   pv = dynamic_cast<PetscVector<Number>*>(nv);
00880   Vec                    v  = pv->vec();
00881   /* Unfortunately, currently this does not produce a ghosted vector, so nonlinear subproblem solves aren't going to be easily available.
00882      Should work fine for getting vectors out for linear subproblem solvers. */
00883   if(dlm->embedding) {
00884     PetscInt n;
00885     ierr = VecCreate(((PetscObject)v)->comm, x);       CHKERRQ(ierr);
00886     ierr = ISGetLocalSize(dlm->embedding, &n);         CHKERRQ(ierr);
00887     ierr = VecSetSizes(*x,n,PETSC_DETERMINE);           CHKERRQ(ierr);
00888     ierr = VecSetType(*x,((PetscObject)v)->type_name); CHKERRQ(ierr);
00889     ierr = VecSetFromOptions(*x);                      CHKERRQ(ierr);
00890     ierr = VecSetUp(*x);                               CHKERRQ(ierr);
00891   }
00892   else {
00893     ierr = VecDuplicate(v,x); CHKERRQ(ierr);
00894   }
00895   ierr = PetscObjectCompose((PetscObject)*x,"DM",(PetscObject)dm); CHKERRQ(ierr);
00896   PetscFunctionReturn(0);
00897 }

PetscErrorCode DMCreateLibMesh ( MPI_Comm  comm,
NonlinearImplicitSystem sys,
DM *  dm 
)

Definition at line 1046 of file petscdmlibmesh.C.

References DMLibMeshSetSystem(), and PetscErrorCode.

Referenced by libMesh::PetscDMNonlinearSolver< T >::init().

01047 {
01048   PetscErrorCode ierr;
01049   PetscFunctionBegin;
01050   ierr = DMCreate(comm, dm);           CHKERRQ(ierr);
01051   ierr = DMSetType(*dm, DMLIBMESH);    CHKERRQ(ierr);
01052   ierr = DMLibMeshSetSystem(*dm, sys); CHKERRQ(ierr);
01053   PetscFunctionReturn(0);
01054 }

static PetscErrorCode DMCreateMatrix_libMesh ( DM  dm,
const   MatType,
Mat *  A 
) [static]

Definition at line 904 of file petscdmlibmesh.C.

References libMesh::ImplicitSystem::matrix, PetscBool, PetscErrorCode, and DM_libMesh::sys.

Referenced by DMCreate_libMesh().

00905 {
00906   PetscFunctionBegin;
00907   PetscErrorCode ierr;
00908   DM_libMesh     *dlm = (DM_libMesh *)(dm->data);
00909   PetscBool eq;
00910 
00911   ierr = PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH, &eq); CHKERRQ(ierr);
00912 
00913   if (!eq)
00914     SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "DM of type %s, not of type %s", ((PetscObject)dm)->type, DMLIBMESH);
00915 
00916   if (!dlm->sys)
00917     SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No libMesh system set for DM_libMesh");
00918 
00919   *A = (dynamic_cast<PetscMatrix<Number>*>(dlm->sys->matrix))->mat();
00920   ierr = PetscObjectReference((PetscObject)(*A)); CHKERRQ(ierr);
00921   PetscFunctionReturn(0);
00922 }

static PetscErrorCode DMDestroy_libMesh ( DM  dm  )  [static]

Definition at line 1026 of file petscdmlibmesh.C.

References DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::embedding, PetscErrorCode, DM_libMesh::varids, and DM_libMesh::varnames.

Referenced by DMCreate_libMesh().

01027 {
01028   DM_libMesh *dlm = (DM_libMesh*)(dm->data);
01029   PetscErrorCode ierr;
01030   PetscFunctionBegin;
01031   delete dlm->varids;
01032   delete dlm->varnames;
01033   delete dlm->blockids;
01034   delete dlm->blocknames;
01035   if(dlm->decomposition) 
01036     delete dlm->decomposition;
01037   ierr = ISDestroy(&dlm->embedding); CHKERRQ(ierr);
01038   ierr = PetscFree(dm->data); CHKERRQ(ierr);
01039 
01040   PetscFunctionReturn(0);
01041 }

static PetscErrorCode DMFunction_libMesh ( DM  dm,
Vec  x,
Vec  r 
) [static]

Definition at line 703 of file petscdmlibmesh.C.

References libMesh::System::current_local_solution, DMLibMeshGetSystem(), libMesh::DofMap::enforce_constraints_exactly(), libMesh::err, libMesh::AutoPtr< Tp >::get(), libMesh::System::get_dof_map(), libMesh::NonlinearImplicitSystem::nonlinear_solver, PetscErrorCode, libMesh::ExplicitSystem::rhs, libMesh::System::solution, and libMesh::System::update().

Referenced by DMSetUp_libMesh().

00704 {
00705   PetscErrorCode ierr;
00706   PetscFunctionBegin;
00707   libmesh_assert(x);
00708   libmesh_assert(r);
00709 
00710   NonlinearImplicitSystem* _sys;
00711   ierr = DMLibMeshGetSystem(dm, _sys); CHKERRQ(ierr);
00712   NonlinearImplicitSystem& sys = *_sys;
00713   PetscVector<Number>& X_sys = *libmesh_cast_ptr<PetscVector<Number>* >(sys.solution.get());
00714   PetscVector<Number>& R_sys = *libmesh_cast_ptr<PetscVector<Number>* >(sys.rhs);
00715   PetscVector<Number> X_global(x), R(r);
00716 
00717   // Use the systems update() to get a good local version of the parallel solution
00718   X_global.swap(X_sys);
00719   R.swap(R_sys);
00720 
00721   _sys->get_dof_map().enforce_constraints_exactly(*_sys);
00722   _sys->update();
00723 
00724   // Swap back
00725   X_global.swap(X_sys);
00726   R.swap(R_sys);
00727   R.zero();
00728 
00729   // if the user has provided both function pointers and objects only the pointer
00730   // will be used, so catch that as an error
00731   if (_sys->nonlinear_solver->residual && _sys->nonlinear_solver->residual_object)
00732     {
00733       libMesh::err << "ERROR: cannot specifiy both a function and object to compute the Residual!" << std::endl;
00734       libmesh_error();
00735     }
00736 
00737   if (_sys->nonlinear_solver->matvec && _sys->nonlinear_solver->residual_and_jacobian_object)
00738     {
00739       libMesh::err << "ERROR: cannot specifiy both a function and object to compute the combined Residual & Jacobian!" << std::endl;
00740       libmesh_error();
00741     }
00742 
00743   if (_sys->nonlinear_solver->residual != NULL)
00744     _sys->nonlinear_solver->residual(*(_sys->current_local_solution.get()), R, *_sys);
00745 
00746   else if (_sys->nonlinear_solver->residual_object != NULL)
00747     _sys->nonlinear_solver->residual_object->residual(*(_sys->current_local_solution.get()), R, *_sys);
00748 
00749   else if (_sys->nonlinear_solver->matvec   != NULL)
00750     _sys->nonlinear_solver->matvec(*(_sys->current_local_solution.get()), &R, NULL, *_sys);
00751 
00752   else if (_sys->nonlinear_solver->residual_and_jacobian_object != NULL)
00753     _sys->nonlinear_solver->residual_and_jacobian_object->residual_and_jacobian(*(_sys->current_local_solution.get()), &R, NULL, *_sys);
00754 
00755   else
00756     libmesh_error();
00757 
00758   R.close();
00759   X_global.close();
00760   PetscFunctionReturn(0);
00761 }

static PetscErrorCode DMJacobian_libMesh ( DM  dm,
Vec  x,
Mat  jac,
Mat  pc,
MatStructure *  msflag 
) [static]

Definition at line 768 of file petscdmlibmesh.C.

References libMesh::SparseMatrix< T >::attach_dof_map(), libMesh::PetscMatrix< T >::close(), libMesh::System::current_local_solution, DMLibMeshGetSystem(), libMesh::DofMap::enforce_constraints_exactly(), libMesh::err, libMesh::AutoPtr< Tp >::get(), libMesh::System::get_dof_map(), libMesh::ImplicitSystem::matrix, libMesh::NonlinearImplicitSystem::nonlinear_solver, PetscErrorCode, libMesh::System::solution, libMesh::PetscMatrix< T >::swap(), libMesh::System::update(), and libMesh::PetscMatrix< T >::zero().

Referenced by DMSetUp_libMesh().

00769 {
00770   PetscErrorCode ierr;
00771   PetscFunctionBegin;
00772   NonlinearImplicitSystem* _sys;
00773   ierr = DMLibMeshGetSystem(dm, _sys); CHKERRQ(ierr);
00774   NonlinearImplicitSystem& sys = *_sys;
00775 
00776   PetscMatrix<Number>  the_pc(pc);
00777   PetscMatrix<Number>  Jac(jac);
00778   PetscVector<Number>& X_sys = *libmesh_cast_ptr<PetscVector<Number>*>(sys.solution.get());
00779   PetscMatrix<Number>& Jac_sys = *libmesh_cast_ptr<PetscMatrix<Number>*>(sys.matrix);
00780   PetscVector<Number>  X_global(x);
00781 
00782   // Set the dof maps
00783   the_pc.attach_dof_map(sys.get_dof_map());
00784   Jac.attach_dof_map(sys.get_dof_map());
00785 
00786   // Use the systems update() to get a good local version of the parallel solution
00787   X_global.swap(X_sys);
00788   Jac.swap(Jac_sys);
00789 
00790   sys.get_dof_map().enforce_constraints_exactly(sys);
00791   sys.update();
00792 
00793   X_global.swap(X_sys);
00794   Jac.swap(Jac_sys);
00795 
00796   the_pc.zero();
00797 
00798   // if the user has provided both function pointers and objects only the pointer
00799   // will be used, so catch that as an error
00800   if (sys.nonlinear_solver->jacobian && sys.nonlinear_solver->jacobian_object)
00801     {
00802       libMesh::err << "ERROR: cannot specifiy both a function and object to compute the Jacobian!" << std::endl;
00803       libmesh_error();
00804     }
00805 
00806   if (sys.nonlinear_solver->matvec && sys.nonlinear_solver->residual_and_jacobian_object)
00807     {
00808       libMesh::err << "ERROR: cannot specifiy both a function and object to compute the combined Residual & Jacobian!" << std::endl;
00809       libmesh_error();
00810     }
00811 
00812   if (sys.nonlinear_solver->jacobian != NULL)
00813     sys.nonlinear_solver->jacobian(*(sys.current_local_solution.get()), the_pc, sys);
00814 
00815   else if (sys.nonlinear_solver->jacobian_object != NULL)
00816     sys.nonlinear_solver->jacobian_object->jacobian(*(sys.current_local_solution.get()), the_pc, sys);
00817 
00818   else if (sys.nonlinear_solver->matvec != NULL)
00819     sys.nonlinear_solver->matvec(*(sys.current_local_solution.get()), NULL, &the_pc, sys);
00820 
00821   else if (sys.nonlinear_solver->residual_and_jacobian_object != NULL)
00822     sys.nonlinear_solver->residual_and_jacobian_object->residual_and_jacobian(*(sys.current_local_solution.get()), NULL, &the_pc, sys);
00823 
00824   else
00825     libmesh_error();
00826 
00827   the_pc.close();
00828   Jac.close();
00829   X_global.close();
00830 
00831   *msflag = SAME_NONZERO_PATTERN;
00832   PetscFunctionReturn(0);
00833 }

PetscErrorCode DMLibMeshCreateDomainDecompositionDM ( DM  dm,
PetscInt  dnumber,
PetscInt dsizes,
char ***  dblocklists,
DM *  ddm 
)

Definition at line 479 of file petscdmlibmesh.C.

References DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DMLibMeshSetUpName_Private(), PetscBool, PetscErrorCode, DM_libMesh::sys, DM_libMesh::varids, and DM_libMesh::varnames.

Referenced by DMCreateDomainDecompositionDM_libMesh().

00480 {
00481   PetscErrorCode ierr;
00482   PetscBool islibmesh;
00483   PetscFunctionBegin;
00484   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
00485   ierr = PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh);
00486   if(!islibmesh) SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM oftype %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
00487   if(dnumber < 0) SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Negative number %D of decomposition parts", dnumber);
00488   PetscValidPointer(ddm,5);
00489   DM_libMesh *dlm = (DM_libMesh *)(dm->data);
00490   ierr = DMCreate(((PetscObject)dm)->comm, ddm); CHKERRQ(ierr);
00491   ierr = DMSetType(*ddm, DMLIBMESH);             CHKERRQ(ierr);
00492   DM_libMesh *ddlm = (DM_libMesh *)((*ddm)->data);
00493   ddlm->sys = dlm->sys;
00494   ddlm->varids   = dlm->varids; 
00495   ddlm->varnames = dlm->varnames; 
00496   ddlm->blockids   = dlm->blockids; 
00497   ddlm->blocknames = dlm->blocknames; 
00498   ddlm->decomposition = new(std::vector<std::set<unsigned int> >);
00499   ddlm->decomposition_type = DMLIBMESH_DOMAIN_DECOMPOSITION;
00500   if(dnumber) {
00501     for(PetscInt d = 0; d < dnumber; ++d) {
00502       if(dsizes[d] < 0) SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Negative size %D of decomposition part %D", dsizes[d],d);
00503       ddlm->decomposition->push_back(std::set<unsigned int>());
00504       for(PetscInt b = 0; b < dsizes[d]; ++b) {
00505         std::string bname(dblocklists[d][b]);
00506         std::map<std::string, unsigned int>::const_iterator bit = dlm->blockids->find(bname);
00507         if(bit == dlm->blockids->end()) 
00508           SETERRQ3(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Block %D on the %D-th list with name %s is not owned by this DM", b, d, dblocklists[d][b]);
00509         unsigned int bid = bit->second;
00510         (*ddlm->decomposition)[d].insert(bid);
00511       }
00512     }
00513   }
00514   else { /* Empty splits indicate default: split all blocks with one per split. */
00515     PetscInt d = 0;
00516     for(std::map<std::string, unsigned int>::const_iterator bit = ddlm->blockids->begin(); bit != ddlm->blockids->end(); ++bit) {
00517       ddlm->decomposition->push_back(std::set<unsigned int>());
00518       unsigned int bid = bit->second;
00519       std::string bname = bit->first;
00520       (*ddlm->decomposition)[d].insert(bid);
00521       ++d;
00522     }
00523   }
00524   ierr = DMLibMeshSetUpName_Private(*ddm); CHKERRQ(ierr);
00525   ierr = DMSetFromOptions(*ddm);           CHKERRQ(ierr);
00526   ierr = DMSetUp(*ddm);                    CHKERRQ(ierr);
00527   PetscFunctionReturn(0);
00528 }

PetscErrorCode DMLibMeshCreateFieldDecompositionDM ( DM  dm,
PetscInt  dnumber,
PetscInt dsizes,
char ***  dvarlists,
DM *  ddm 
)

Definition at line 426 of file petscdmlibmesh.C.

References DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DMLibMeshSetUpName_Private(), PetscBool, PetscErrorCode, DM_libMesh::sys, DM_libMesh::varids, and DM_libMesh::varnames.

Referenced by DMCreateFieldDecompositionDM_libMesh().

00427 {
00428   PetscErrorCode ierr;
00429   PetscBool islibmesh;
00430   PetscFunctionBegin;
00431   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
00432   ierr = PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh);
00433   if(!islibmesh) SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM oftype %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
00434   if(dnumber < 0) SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Negative number %D of decomposition parts", dnumber);
00435   PetscValidPointer(ddm,5);
00436   DM_libMesh *dlm = (DM_libMesh *)(dm->data);
00437   ierr = DMCreate(((PetscObject)dm)->comm, ddm); CHKERRQ(ierr);
00438   ierr = DMSetType(*ddm, DMLIBMESH);             CHKERRQ(ierr);
00439   DM_libMesh *ddlm = (DM_libMesh *)((*ddm)->data);
00440   ddlm->sys = dlm->sys;
00441   ddlm->varids = dlm->varids; 
00442   ddlm->varnames = dlm->varnames; 
00443   ddlm->blockids = dlm->blockids;
00444   ddlm->blocknames = dlm->blocknames;
00445   ddlm->decomposition = new(std::vector<std::set<unsigned int> >);
00446   ddlm->decomposition_type = DMLIBMESH_FIELD_DECOMPOSITION;
00447   if(dnumber) {
00448     for(PetscInt d = 0; d < dnumber; ++d) {
00449       if(dsizes[d] < 0) SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Negative size %D of decomposition part %D", dsizes[d],d);
00450       ddlm->decomposition->push_back(std::set<unsigned int>());
00451       for(PetscInt v = 0; v < dsizes[d]; ++v) {
00452         std::string vname(dvarlists[d][v]);
00453         std::map<std::string, unsigned int>::const_iterator vit = dlm->varids->find(vname);
00454         if(vit == dlm->varids->end()) 
00455           SETERRQ3(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Variable %D on the %D-th list with name %s is not owned by this DM", v, d, dvarlists[d][v]);
00456         unsigned int vid = vit->second;
00457         (*ddlm->decomposition)[d].insert(vid);
00458       }
00459     }
00460   }
00461   else { /* Empty splits indicate default: split all variables with one per split. */
00462     PetscInt d = 0;
00463     for(std::map<std::string, unsigned int>::const_iterator vit = ddlm->varids->begin(); vit != ddlm->varids->end(); ++vit) {
00464       ddlm->decomposition->push_back(std::set<unsigned int>());
00465       unsigned int vid = vit->second;
00466       std::string vname = vit->first;
00467       (*ddlm->decomposition)[d].insert(vid);
00468       ++d;
00469     }
00470   }
00471   ierr = DMLibMeshSetUpName_Private(*ddm); CHKERRQ(ierr);
00472   ierr = DMSetFromOptions(*ddm);           CHKERRQ(ierr);
00473   ierr = DMSetUp(*ddm);                    CHKERRQ(ierr);
00474   PetscFunctionReturn(0);
00475 }

PetscErrorCode DMLibMeshGetBlocks ( DM  dm,
PetscInt n,
char ***  blocknames 
)

Definition at line 45 of file petscdmlibmesh.C.

References DM_libMesh::blockids, PetscBool, and PetscErrorCode.

00046 {
00047   PetscErrorCode ierr;
00048   PetscInt i;
00049   PetscFunctionBegin;
00050   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
00051   PetscBool islibmesh;
00052   ierr = PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh);
00053   if(!islibmesh) SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM oftype %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
00054   DM_libMesh *dlm = (DM_libMesh *)(dm->data);
00055   PetscValidPointer(n,2);
00056   *n = dlm->blockids->size();
00057   if(!blocknames) PetscFunctionReturn(0);
00058   ierr = PetscMalloc(*n*sizeof(char*), blocknames); CHKERRQ(ierr);
00059   i = 0;
00060   for(std::map<std::string, unsigned int>::const_iterator it = dlm->blockids->begin(); it != dlm->blockids->end(); ++it){
00061     ierr = PetscStrallocpy(it->first.c_str(), *blocknames+i); CHKERRQ(ierr);
00062     ++i;
00063   }
00064   PetscFunctionReturn(0);
00065 }

PetscErrorCode DMLibMeshGetSystem ( DM  dm,
NonlinearImplicitSystem *&  sys 
)

Definition at line 203 of file petscdmlibmesh.C.

References PetscBool, PetscErrorCode, and DM_libMesh::sys.

Referenced by DMFunction_libMesh(), DMJacobian_libMesh(), and DMVariableBounds_libMesh().

00204 {
00205   PetscErrorCode ierr;
00206   PetscFunctionBegin;
00207   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
00208   PetscBool islibmesh;
00209   ierr = PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh); CHKERRQ(ierr);
00210   if(!islibmesh) SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM oftype %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
00211   DM_libMesh *dlm = (DM_libMesh *)(dm->data);
00212   sys = dlm->sys;
00213   PetscFunctionReturn(0);
00214 }

PetscErrorCode DMLibMeshGetVariables ( DM  dm,
PetscInt n,
char ***  varnames 
)

Definition at line 69 of file petscdmlibmesh.C.

References PetscBool, PetscErrorCode, and DM_libMesh::varids.

00070 {
00071   PetscErrorCode ierr;
00072   PetscFunctionBegin;
00073   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
00074   PetscBool islibmesh;
00075   PetscInt i;
00076   ierr = PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh);
00077   if(!islibmesh) SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM oftype %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
00078   DM_libMesh *dlm = (DM_libMesh *)(dm->data);
00079   PetscValidPointer(n,2);
00080   *n = dlm->varids->size();
00081   if(!varnames) PetscFunctionReturn(0);
00082   ierr = PetscMalloc(*n*sizeof(char*), varnames); CHKERRQ(ierr);
00083   i = 0;
00084   for(std::map<std::string, unsigned int>::const_iterator it = dlm->varids->begin(); it != dlm->varids->end(); ++it){
00085     ierr = PetscStrallocpy(it->first.c_str(), *varnames+i); CHKERRQ(ierr);
00086     ++i;
00087   }
00088   PetscFunctionReturn(0);
00089 }

static PetscErrorCode DMLibMeshParseDecompositionDescriptor_Private ( DM  dm,
const char *  ddesc,
PetscInt dtype,
PetscInt dcount,
PetscInt **  dsizes,
char ****  dlists 
) [static]

Definition at line 536 of file petscdmlibmesh.C.

References token::next, PetscBool, PetscErrorCode, and token::s.

Referenced by DMCreateDomainDecompositionDM_libMesh(), and DMCreateFieldDecompositionDM_libMesh().

00537 {
00538   PetscFunctionBegin;
00539   PetscErrorCode ierr;
00540   PetscBool eq;
00541   char *s0, *s, *ss;
00542   struct token *llfirst = PETSC_NULL, *lllast = PETSC_NULL, *tok;
00543   PetscInt stcount = 0, brcount = 0, d, i;
00544   size_t len0, count;
00545   
00546   /* 
00547      Parse the decomposition descriptor. 
00548      Decomposition names could be of one of two forms:
00549      var:v1,v2;v3,v4;v4,v5;
00550      block:b1,b2;b3,b4;b4,b5;
00551      resulting in an overlapping decomposition that groups 
00552      variables (v1,v2), (v3,v4), (v4,v5) or
00553      blocks    (b1,b2), (b3,b4), (b4,b5).
00554   */
00555   /* Copy the descriptor so that we can manipulate it in place. */
00556   ierr = PetscStrallocpy(ddesc,&s0);   CHKERRQ(ierr);
00557   ierr = PetscStrlen(s0, &len0)  ;     CHKERRQ(ierr);
00558   ierr = PetscStrstr(s0,":",&ss);      CHKERRQ(ierr);
00559   if(!ss) {
00560     ss = s0+len0;
00561   }
00562   else {
00563     *ss = 0;
00564   }
00565   ierr = PetscStrcmp(s0,"var",&eq);    CHKERRQ(ierr);
00566   if(eq) {
00567     *dtype=DMLIBMESH_FIELD_DECOMPOSITION;
00568   }
00569   else {
00570     ierr = PetscStrcmp(s0,"block",&eq);CHKERRQ(ierr);
00571     if(!eq)   
00572       SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Could not determine decomposition type from descriptor: %s\n", ddesc); CHKERRQ(ierr);
00573     *dtype=DMLIBMESH_DOMAIN_DECOMPOSITION;
00574   }
00575   ierr = PetscStrlen(s0,&count);       CHKERRQ(ierr);
00576   while(count < len0) {
00577     struct token *st, *br;
00578     ++ss; ++count; 
00579     s=ss;
00580     while(*ss && *ss != ',' && *ss != ';') {
00581       ++ss; ++count;
00582     }
00583     st = PETSC_NULL; br = PETSC_NULL;
00584     if(*ss) {
00585       /* 
00586          Found a separator, or a break.
00587          Add an appropriate token to the list.
00588          A token separator ',' produces no token. 
00589       */
00590       if(*ss == ';') {
00591         /* Create a break token: a token with a null string. */
00592         ierr = PetscNew(struct token, &br); CHKERRQ(ierr);
00593       }
00594       *ss = 0;
00595       if(s != ss) {
00596         /* A nonempty string. */
00597         ierr = PetscNew(struct token, &st); CHKERRQ(ierr);
00598         st->s = s; /* The string will be properly copied below. */
00599       }
00600       /* Add the new tokens to the list. */
00601       if(st) {
00602         if(!lllast) {
00603           llfirst = lllast = st;
00604         }
00605         else {
00606           lllast->next = st; lllast = st;
00607         }
00608       }
00609       if(br) {
00610         if(!lllast) {
00611           llfirst = lllast = br;
00612         }
00613         else {
00614           lllast->next = br; lllast = br;
00615         }
00616       }
00617     }
00618   } 
00619   /* The result of parsing is in the linked list ll. */
00620   /* Count up the strings and the breaks. */
00621   tok = llfirst;
00622   while(tok) {
00623     if(tok->s) 
00624       ++stcount;
00625     else 
00626       ++brcount;
00627     tok = tok->next;
00628   }
00629   /* Allocate the space for the output. */
00630   *dcount = brcount;
00631   ierr = PetscMalloc(*dcount*sizeof(PetscInt), dsizes); CHKERRQ(ierr);
00632   ierr = PetscMalloc(*dcount*sizeof(char**),   dlists); CHKERRQ(ierr);
00633   for(d = 0; d < *dcount; ++d) (*dsizes)[d] = 0;
00634   tok = llfirst; d = 0;
00635   while(tok) {
00636     if(tok->s) 
00637       ++(*dsizes)[d];
00638     else 
00639       ++d;
00640     tok = tok->next;
00641   }
00642   for(d = 0; d < *dcount; ++d) {
00643     ierr = PetscMalloc(sizeof(char**)*(*dsizes)[d], (*dlists)+d); CHKERRQ(ierr);
00644   }
00645   /* Now copy strings and destroy tokens. */
00646   tok = llfirst; d = 0; i = 0;
00647   while(tok) {
00648     if(tok->s) {
00649       ierr = PetscStrallocpy(tok->s, (*dlists)[d]+i); CHKERRQ(ierr);
00650       ++i;
00651     }
00652     else {
00653       ++d;
00654       i = 0;
00655     }
00656     llfirst = tok;
00657     tok = tok->next;
00658     ierr = PetscFree(llfirst); CHKERRQ(ierr);
00659   }
00660   /* Deallocate workspace. */
00661   ierr = PetscFree(s0); CHKERRQ(ierr);
00662   PetscFunctionReturn(0);
00663 }

PetscErrorCode DMLibMeshSetSystem ( DM  dm,
NonlinearImplicitSystem sys 
)

Definition at line 142 of file petscdmlibmesh.C.

References libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), DM_libMesh::blockids, DM_libMesh::blocknames, libMesh::CommWorld, DMLibMeshSetUpName_Private(), end, libMesh::System::get_dof_map(), libMesh::System::get_mesh(), mesh, libMesh::DofMap::n_variables(), libMesh::Variable::name(), PetscBool, PetscErrorCode, libMesh::Parallel::Communicator::set_union(), libMesh::MeshBase::subdomain_name(), DM_libMesh::sys, libMesh::DofMap::variable(), DM_libMesh::varids, and DM_libMesh::varnames.

Referenced by DMCreateLibMesh().

00143 {
00144   PetscErrorCode ierr;
00145   PetscFunctionBegin;
00146   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
00147   PetscBool islibmesh;
00148   ierr = PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh);
00149   if(!islibmesh) SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM oftype %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
00150   
00151   if(dm->setupcalled) SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot reset the libMesh system after DM has been set up.");
00152   DM_libMesh *dlm = (DM_libMesh *)(dm->data);
00153   dlm->sys =&sys;
00154   /* Initially populate the sets of active blockids and varids using all of the 
00155      existing blocks/variables (only variables are supported at the moment). */
00156   DofMap& dofmap = dlm->sys->get_dof_map();
00157   dlm->varids->clear();
00158   dlm->varnames->clear();
00159   for(unsigned int v = 0; v < dofmap.n_variables(); ++v) {
00160     std::string vname = dofmap.variable(v).name();
00161     dlm->varids->insert(std::pair<std::string,unsigned int>(vname,v));
00162     dlm->varnames->insert(std::pair<unsigned int,std::string>(v,vname));
00163   }
00164   const MeshBase& mesh = dlm->sys->get_mesh();
00165   dlm->blockids->clear();
00166   dlm->blocknames->clear();
00167   std::set<subdomain_id_type> blocks;
00168   /* The following effectively is a verbatim copy of MeshBase::n_subdomains(). */
00169   // This requires an inspection on every processor
00170   parallel_only();
00171   MeshBase::const_element_iterator       el  = mesh.active_elements_begin();
00172   const MeshBase::const_element_iterator end = mesh.active_elements_end();
00173   for (; el!=end; ++el)
00174     blocks.insert((*el)->subdomain_id());
00175   // Some subdomains may only live on other processors
00176   CommWorld.set_union(blocks);
00177 
00178   std::set<subdomain_id_type>::iterator bit = blocks.begin();
00179   std::set<subdomain_id_type>::iterator bend = blocks.end();
00180   if(bit == bend) SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "No mesh blocks found.");
00181 
00182   for(; bit != bend; ++bit) {
00183     subdomain_id_type bid = *bit;
00184     std::string bname = mesh.subdomain_name(bid);
00185     if(!bname.length()) {
00186       /* Block names are currently implemented for Exodus II meshes 
00187          only, so we might have to make up our own block names and 
00188          maintain our own mapping of block ids to names. 
00189       */
00190       std::ostringstream ss;
00191       ss << "dm" << bid;
00192       bname = ss.str();
00193     }
00194     dlm->blockids->insert(std::pair<std::string,unsigned int>(bname,bid));
00195     dlm->blocknames->insert(std::pair<unsigned int,std::string>(bid,bname));
00196   }
00197   ierr = DMLibMeshSetUpName_Private(dm); CHKERRQ(ierr);
00198   PetscFunctionReturn(0);
00199 }

PetscErrorCode DMLibMeshSetUpName_Private ( DM  dm  ) 

Definition at line 93 of file petscdmlibmesh.C.

References DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DM_libMesh::embedding_type, end, libMesh::System::name(), libMesh::Quality::name(), PetscErrorCode, DM_libMesh::sys, and DM_libMesh::varnames.

Referenced by DMCreateDomainDecomposition_libMesh(), DMCreateFieldDecomposition_libMesh(), DMLibMeshCreateDomainDecompositionDM(), DMLibMeshCreateFieldDecompositionDM(), and DMLibMeshSetSystem().

00094 {
00095   DM_libMesh* dlm = (DM_libMesh*)dm->data;
00096   PetscErrorCode ierr;
00097   PetscFunctionBegin;
00098   std::string name = dlm->sys->name();
00099   std::map<unsigned int, std::string> *dnames = PETSC_NULL, *enames = PETSC_NULL;
00100   if(dlm->decomposition_type == DMLIBMESH_FIELD_DECOMPOSITION) {
00101     name += ":dec:var:";
00102     dnames = dlm->varnames;
00103   }
00104   if(dlm->decomposition_type == DMLIBMESH_DOMAIN_DECOMPOSITION) {
00105     name += ":dec:block:";
00106     dnames = dlm->blocknames;
00107   }
00108   if(dnames) {
00109     for(unsigned int d = 0; d < dlm->decomposition->size(); ++d) {
00110       for(std::set<unsigned int>::iterator dit = (*dlm->decomposition)[d].begin(); dit != (*dlm->decomposition)[d].end(); ++dit) {
00111         unsigned int id = *dit;
00112         if(dit != (*dlm->decomposition)[d].begin())
00113           name += ",";
00114         name += (*dnames)[id];
00115       }
00116       name += ";";
00117     }
00118   }
00119   if(dlm->embedding_type == DMLIBMESH_FIELD_EMBEDDING) {
00120     name += ":emb:var:";
00121     enames = dlm->varnames;
00122   }
00123   if(dlm->embedding_type == DMLIBMESH_DOMAIN_EMBEDDING) {
00124     name += ":emb:block:";
00125     enames = dlm->blocknames;
00126   }
00127   if(enames) {
00128     for(std::map<unsigned int, std::string>::iterator eit = enames->begin(); eit != enames->end(); ++eit) {
00129       std::string ename = eit->second;
00130       if(eit != enames->begin())
00131         name += ",";
00132       name += ename;
00133     }
00134     name += ";";
00135   }
00136   ierr = PetscObjectSetName((PetscObject)dm, name.c_str()); CHKERRQ(ierr);
00137   PetscFunctionReturn(0);
00138 }

static PetscErrorCode DMSetUp_libMesh ( DM  dm  )  [static]

Definition at line 986 of file petscdmlibmesh.C.

References DMFunction_libMesh(), DMJacobian_libMesh(), DMVariableBounds_libMesh(), DM_libMesh::embedding, libMesh::NonlinearImplicitSystem::nonlinear_solver, PetscBool, PetscErrorCode, and DM_libMesh::sys.

Referenced by DMCreate_libMesh().

00987 {
00988   PetscFunctionBegin;
00989   PetscErrorCode ierr;
00990   DM_libMesh     *dlm = (DM_libMesh *)(dm->data);
00991   PetscBool eq;
00992 
00993   ierr = PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH, &eq); CHKERRQ(ierr);
00994 
00995   if (!eq)
00996     SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "DM of type %s, not of type %s", ((PetscObject)dm)->type, DMLIBMESH);
00997 
00998   if (!dlm->sys)
00999     SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No libMesh system set for DM_libMesh");
01000   /* 
01001      Do not evaluate function, Jacobian or bounds for an embedded DM -- the subproblem might not have enough information for that. 
01002   */
01003   if(!dlm->embedding) {
01004     ierr = DMSetFunction(dm, DMFunction_libMesh); CHKERRQ(ierr);
01005     ierr = DMSetJacobian(dm, DMJacobian_libMesh); CHKERRQ(ierr);
01006     if (dlm->sys->nonlinear_solver->bounds || dlm->sys->nonlinear_solver->bounds_object)
01007       ierr = DMSetVariableBounds(dm, DMVariableBounds_libMesh); CHKERRQ(ierr);
01008     
01009   }
01010   else {
01011     /* 
01012        Fow now we don't implement even these, although a linear "Dirichlet" subproblem is well-defined.
01013        Creating the submatrix, however, might require extracting the submatrix preallocation from an unassembled matrix.
01014     */
01015       dm->ops->createglobalvector = 0;
01016       dm->ops->creatematrix = 0;
01017   }
01018   PetscFunctionReturn(0);
01019 }

static PetscErrorCode DMVariableBounds_libMesh ( DM  dm,
Vec  xl,
Vec  xu 
) [static]

Definition at line 838 of file petscdmlibmesh.C.

References DMLibMeshGetSystem(), libMesh::NonlinearImplicitSystem::nonlinear_solver, and PetscErrorCode.

Referenced by DMSetUp_libMesh().

00839 {
00840   PetscErrorCode ierr;
00841   NonlinearImplicitSystem* _sys;
00842   ierr = DMLibMeshGetSystem(dm, _sys); CHKERRQ(ierr);
00843   NonlinearImplicitSystem& sys = *_sys;
00844   PetscVector<Number> XL(xl);
00845   PetscVector<Number> XU(xu);
00846   PetscFunctionBegin;
00847 
00848   ierr = VecSet(xl, SNES_VI_NINF); CHKERRQ(ierr);
00849   ierr = VecSet(xu, SNES_VI_INF);  CHKERRQ(ierr);
00850   if (sys.nonlinear_solver->bounds != NULL)
00851     sys.nonlinear_solver->bounds(XL,XU,sys);
00852   else if (sys.nonlinear_solver->bounds_object != NULL)
00853     sys.nonlinear_solver->bounds_object->bounds(XL,XU, sys);
00854   else
00855     SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "No bounds calculation in this libMesh object");
00856 
00857   PetscFunctionReturn(0);
00858 }

static PetscErrorCode DMView_libMesh ( DM  dm,
PetscViewer  viewer 
) [static]

Definition at line 927 of file petscdmlibmesh.C.

References DM_libMesh::blockids, DM_libMesh::decomposition, DM_libMesh::decomposition_type, end, libMesh::Quality::name(), PetscBool, PetscErrorCode, and DM_libMesh::varids.

Referenced by DMCreate_libMesh().

00928 {
00929   PetscErrorCode ierr;
00930   PetscBool isascii;
00931   const char *name, *prefix;
00932   DM_libMesh *dlm = (DM_libMesh*)dm->data;
00933   PetscFunctionBegin;
00934   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii); CHKERRQ(ierr);
00935   if(isascii) {
00936     ierr = PetscObjectGetName((PetscObject)dm, &name);     CHKERRQ(ierr);
00937     ierr = PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix); CHKERRQ(ierr);
00938     ierr = PetscViewerASCIIPrintf(viewer, "DM libMesh with name %s and prefix %s\n", name, prefix); CHKERRQ(ierr);
00939     ierr = PetscViewerASCIIPrintf(viewer, "blocks:", name, prefix); CHKERRQ(ierr);
00940     std::map<std::string,unsigned int>::iterator bit = dlm->blockids->begin();
00941     std::map<std::string,unsigned int>::const_iterator bend = dlm->blockids->end();
00942     for(; bit != bend; ++bit) {
00943       ierr = PetscViewerASCIIPrintf(viewer, "(%s,%D) ", bit->first.c_str(), bit->second); CHKERRQ(ierr);
00944     }
00945     ierr = PetscViewerASCIIPrintf(viewer, "\n"); CHKERRQ(ierr);
00946     ierr = PetscViewerASCIIPrintf(viewer, "variables:", name, prefix); CHKERRQ(ierr);
00947     std::map<std::string,unsigned int>::iterator vit = dlm->varids->begin();
00948     std::map<std::string,unsigned int>::const_iterator vend = dlm->varids->end();
00949     for(; vit != vend; ++vit) {
00950       ierr = PetscViewerASCIIPrintf(viewer, "(%s,%D) ", vit->first.c_str(), vit->second); CHKERRQ(ierr);
00951     }
00952     ierr = PetscViewerASCIIPrintf(viewer, "\n"); CHKERRQ(ierr);
00953     if(dlm->decomposition_type == DMLIBMESH_NO_DECOMPOSITION) {
00954       ierr = PetscViewerASCIIPrintf(viewer, "No decomposition\n"); CHKERRQ(ierr);
00955     }
00956     else {
00957       if(dlm->decomposition_type == DMLIBMESH_FIELD_DECOMPOSITION) {
00958         ierr = PetscViewerASCIIPrintf(viewer, "Field decomposition by variable: "); CHKERRQ(ierr);
00959       }
00960       else if(dlm->decomposition_type == DMLIBMESH_DOMAIN_DECOMPOSITION) {
00961         ierr = PetscViewerASCIIPrintf(viewer, "Domain decomposition by block: "); CHKERRQ(ierr);
00962       }
00963       else SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "Unexpected decomposition type: %D", dlm->decomposition_type);
00964       /* FIX: decompositions might have different sizes and components on different ranks. */
00965       for(unsigned int d = 0; d < dlm->decomposition->size(); ++d) {
00966         std::set<unsigned int>::iterator dbegin  = (*dlm->decomposition)[d].begin();
00967         std::set<unsigned int>::iterator dit     = (*dlm->decomposition)[d].begin();
00968         std::set<unsigned int>::iterator dend    = (*dlm->decomposition)[d].end();      
00969         for(; dit != dend; ++dit) {
00970           if(dit != dbegin) {
00971             ierr = PetscViewerASCIIPrintf(viewer, ","); CHKERRQ(ierr);
00972           }
00973           ierr = PetscViewerASCIIPrintf(viewer, "%D", *dit); CHKERRQ(ierr);
00974         }
00975         ierr = PetscViewerASCIIPrintf(viewer, ";"); CHKERRQ(ierr);
00976       }
00977       ierr = PetscViewerASCIIPrintf(viewer, "\n"); CHKERRQ(ierr);
00978     }
00979   }
00980 
00981   PetscFunctionReturn(0);
00982 }


Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:49 UTC

Hosted By:
SourceForge.net Logo