git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@3633 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp
2010-01-08 22:54:13 +00:00
parent 654e03d382
commit e3c029753d
26 changed files with 2110 additions and 136 deletions

View File

@ -46,20 +46,35 @@ RegUnion::RegUnion(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg)
}
// extent of union of regions
// has bounding box if interior and all sub-regions have bounding box
Region **regions = domain->regions;
extent_xlo = extent_ylo = extent_zlo = BIG;
extent_xhi = extent_yhi = extent_zhi = -BIG;
bboxflag = 1;
for (int ilist = 0; ilist < nregion; ilist++)
if (regions[list[ilist]]->bboxflag == 0) bboxflag = 0;
if (!interior) bboxflag = 0;
for (int ilist = 0; ilist < nregion; ilist++) {
extent_xlo = MIN(extent_xlo,regions[list[ilist]]->extent_xlo);
extent_ylo = MIN(extent_ylo,regions[list[ilist]]->extent_ylo);
extent_zlo = MIN(extent_zlo,regions[list[ilist]]->extent_zlo);
extent_xhi = MAX(extent_xhi,regions[list[ilist]]->extent_xhi);
extent_yhi = MAX(extent_yhi,regions[list[ilist]]->extent_yhi);
extent_zhi = MAX(extent_zhi,regions[list[ilist]]->extent_zhi);
if (bboxflag) {
extent_xlo = extent_ylo = extent_zlo = BIG;
extent_xhi = extent_yhi = extent_zhi = -BIG;
for (int ilist = 0; ilist < nregion; ilist++) {
extent_xlo = MIN(extent_xlo,regions[list[ilist]]->extent_xlo);
extent_ylo = MIN(extent_ylo,regions[list[ilist]]->extent_ylo);
extent_zlo = MIN(extent_zlo,regions[list[ilist]]->extent_zlo);
extent_xhi = MAX(extent_xhi,regions[list[ilist]]->extent_xhi);
extent_yhi = MAX(extent_yhi,regions[list[ilist]]->extent_yhi);
extent_zhi = MAX(extent_zhi,regions[list[ilist]]->extent_zhi);
}
}
// possible contacts = sum of possible contacts in all sub-regions
cmax = 0;
for (int ilist = 0; ilist < nregion; ilist++)
cmax += regions[list[ilist]]->cmax;
contact = new Contact[cmax];
}
/* ---------------------------------------------------------------------- */
@ -67,9 +82,13 @@ RegUnion::RegUnion(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg)
RegUnion::~RegUnion()
{
delete [] list;
delete [] contact;
}
/* ---------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
inside = 1 if x,y,z is match() with any sub-region
else inside = 0
------------------------------------------------------------------------- */
int RegUnion::match(double x, double y, double z)
{
@ -78,9 +97,95 @@ int RegUnion::match(double x, double y, double z)
for (ilist = 0; ilist < nregion; ilist++)
if (regions[list[ilist]]->match(x,y,z)) break;
int inside; // inside if matched any region
int inside = 1; // inside if matched any region
if (ilist == nregion) inside = 0;
else inside = 1;
return !(inside ^ interior); // 1 if same, 0 if different
}
/* ----------------------------------------------------------------------
compute contacts with interior of union of sub-regions
(1) compute contacts in each sub-region
(2) only keep a contact if surface point is not match() to all other regions
------------------------------------------------------------------------- */
int RegUnion::surface_interior(double *x, double cutoff)
{
int m,ilist,jlist,iregion,jregion,ncontacts;
double xs,ys,zs;
Region **regions = domain->regions;
int n = 0;
for (ilist = 0; ilist < nregion; ilist++) {
iregion = list[ilist];
ncontacts = regions[iregion]->surface(x,cutoff);
for (m = 0; m < ncontacts; m++) {
xs = x[0] - regions[iregion]->contact[m].delx;
ys = x[1] - regions[iregion]->contact[m].dely;
zs = x[2] - regions[iregion]->contact[m].delz;
for (jlist = 0; jlist < nregion; jlist++) {
if (jlist == ilist) continue;
jregion = list[jlist];
if (regions[jregion]->match(xs,ys,zs)) break;
}
if (jlist == nregion) {
contact[n].r = regions[iregion]->contact[m].r;
contact[n].delx = regions[iregion]->contact[m].delx;
contact[n].dely = regions[iregion]->contact[m].dely;
contact[n].delz = regions[iregion]->contact[m].delz;
n++;
}
}
}
return n;
}
/* ----------------------------------------------------------------------
compute contacts with exterior of union of sub-regions
(1) flip interior/exterior flag of each sub-region
(2) compute contacts in each sub-region
(3) only keep a contact if surface point is match() to all other regions
(4) flip interior/exterior flags back to original settings
this is effectively same algorithm as surface_interior() for RegIntersect
------------------------------------------------------------------------- */
int RegUnion::surface_exterior(double *x, double cutoff)
{
int m,ilist,jlist,iregion,jregion,ncontacts;
double xs,ys,zs;
Region **regions = domain->regions;
int n = 0;
for (ilist = 0; ilist < nregion; ilist++)
regions[list[ilist]]->interior ^= 1;
for (ilist = 0; ilist < nregion; ilist++) {
iregion = list[ilist];
ncontacts = regions[iregion]->surface(x,cutoff);
for (m = 0; m < ncontacts; m++) {
xs = x[0] - regions[iregion]->contact[m].delx;
ys = x[1] - regions[iregion]->contact[m].dely;
zs = x[2] - regions[iregion]->contact[m].delz;
for (jlist = 0; jlist < nregion; jlist++) {
if (jlist == ilist) continue;
jregion = list[jlist];
if (!regions[jregion]->match(xs,ys,zs)) break;
}
if (jlist == nregion) {
contact[n].r = regions[iregion]->contact[m].r;
contact[n].delx = regions[iregion]->contact[m].delx;
contact[n].dely = regions[iregion]->contact[m].dely;
contact[n].delz = regions[iregion]->contact[m].delz;
n++;
}
}
}
for (ilist = 0; ilist < nregion; ilist++)
regions[list[ilist]]->interior ^= 1;
return n;
}