/** Finds oldNode in n's node adjacency list, and replaces it with newNode */ void FEM_Mesh::n2n_replace(int n, int oldNode, int newNode) { if (n == -1) return; if(FEM_Is_ghost_index(n)){ FEM_VarIndexAttribute *nAdj = (FEM_VarIndexAttribute *)node.getGhost()->lookup(FEM_NODE_NODE_ADJACENCY,"n2n_replace"); CkVec<CkVec<ElemID> > &nVec = nAdj->get(); CkVec<ElemID> &nsVec = nVec[FEM_To_ghost_index(n)]; for (int i=0; i<nsVec.length(); i++) { if (nsVec[i].getSignedId() == oldNode) { nsVec[i] = ElemID(0,newNode); break; } } } else { FEM_VarIndexAttribute *nAdj = (FEM_VarIndexAttribute *)node.lookup(FEM_NODE_NODE_ADJACENCY,"n2n_replace"); CkVec<CkVec<ElemID> > &nVec = nAdj->get(); CkVec<ElemID> &nsVec = nVec[n]; for (int i=0; i<nsVec.length(); i++) { if (nsVec[i].getSignedId() == oldNode) { nsVec[i] = ElemID(0,newNode); break; } } } }
/** Finds oldElem in n's element adjacency list, and replaces it with newElem */ void FEM_Mesh::n2e_replace(int n, int oldElem, int newElem) { if (n == -1) return; if(FEM_Is_ghost_index(n)){ FEM_VarIndexAttribute *eAdj = (FEM_VarIndexAttribute *)node.getGhost()->lookup(FEM_NODE_ELEM_ADJACENCY,"n2e_replace"); CkVec<CkVec<ElemID> > &eVec = eAdj->get(); CkVec<ElemID> &nsVec = eVec[FEM_To_ghost_index(n)]; for (int i=0; i<nsVec.length(); i++) { if (nsVec[i].getSignedId() == oldElem) { nsVec[i] = ElemID(0,newElem); break; } } int *testn2e, testn2ec; n2e_getAll(n,testn2e,testn2ec); for(int i=0; i<testn2ec; i++) { if(FEM_Is_ghost_index(testn2e[i])) CkAssert(elem[0].ghost->is_valid(FEM_From_ghost_index(testn2e[i]))); else CkAssert(elem[0].is_valid(testn2e[i])); } if(testn2ec!=0) delete[] testn2e; } else{ FEM_VarIndexAttribute *eAdj = (FEM_VarIndexAttribute *)node.lookup(FEM_NODE_ELEM_ADJACENCY,"n2e_replace"); CkVec<CkVec<ElemID> > &eVec = eAdj->get(); CkVec<ElemID> &nsVec = eVec[n]; for (int i=0; i<nsVec.length(); i++) { if (nsVec[i].getSignedId() == oldElem) { nsVec[i] = ElemID(0,newElem); break; } } } }
// Update Strains for this particle // Velocities for all fields are present on the nodes // matRef is the material and properties have been loaded, matFld is the material field void MatPointAS::UpdateStrain(double strainTime,int secondPass,int np,void *props,int matFld) { int i,numnds,nds[maxShapeNodes]; double fn[maxShapeNodes],xDeriv[maxShapeNodes],yDeriv[maxShapeNodes],zDeriv[maxShapeNodes]; Vector vel; Matrix3 dv; // don't need to zero zDeriv because always set in axisymmetric shape functions // find shape functions and derviatives const ElementBase *elemRef = theElements[ElemID()]; elemRef->GetShapeGradients(&numnds,fn,nds,xDeriv,yDeriv,zDeriv,this); // Find strain rates at particle from current grid velocities // and using the velocity field for that particle and each node and the right material // In axisymmetric x->r, y->z, and z->hoop for(i=1;i<=numnds;i++) { vel=nd[nds[i]]->GetVelocity((short)vfld[i],matFld); dv += Matrix3(vel.x*xDeriv[i],vel.x*yDeriv[i],vel.y*xDeriv[i],vel.y*yDeriv[i],vel.x*zDeriv[i]); } // save velocity gradient (if needed for J integral calculation) SetVelocityGradient(dv(0,0),dv(1,0),dv(0,1),dv(1,0),secondPass); // convert to strain increments // e.g., now dvrr = dvr/dr * dt = d/dr(du/dt) * dt = d/dt(du/dr) * dt = du/dr) dv.Scale(strainTime); // find effective particle transport properties from grid results ResidualStrains res; res.dT = 0; res.dC = 0.; if(!ConductionTask::active) { res.dT = pTemperature-pPreviousTemperature; pPreviousTemperature = pTemperature; } else { for(i=1;i<=numnds;i++) res.dT += conduction->IncrementValueExtrap(nd[nds[i]],fn[i]); res.dT = conduction->GetDeltaValue(this,res.dT); } if(DiffusionTask::active) { for(i=1;i<=numnds;i++) res.dC += diffusion->IncrementValueExtrap(nd[nds[i]],fn[i]); res.dC = diffusion->GetDeltaValue(this,res.dC); } // pass on to material class to handle PerformConstitutiveLaw(dv,strainTime,np,props,&res); }