void GMSH_CutGridPlugin::getPoint(int iU, int iV, double *X) { double u = getNbU() > 1 ? (double)iU / (double)(getNbU() - 1.) : 0.; double v = getNbV() > 1 ? (double)iV / (double)(getNbV() - 1.) : 0.; X[0] = CutGridOptions_Number[0].def + u * (CutGridOptions_Number[3].def-CutGridOptions_Number[0].def) + v * (CutGridOptions_Number[6].def-CutGridOptions_Number[0].def); X[1] = CutGridOptions_Number[1].def + u * (CutGridOptions_Number[4].def-CutGridOptions_Number[1].def) + v * (CutGridOptions_Number[7].def-CutGridOptions_Number[1].def); X[2] = CutGridOptions_Number[2].def + u * (CutGridOptions_Number[5].def-CutGridOptions_Number[2].def) + v * (CutGridOptions_Number[8].def-CutGridOptions_Number[2].def); }
void GMSH_CutGridPlugin::draw(void *context) { #if defined(HAVE_OPENGL) glColor4ubv((GLubyte *) & CTX::instance()->color.fg); double p[3]; drawContext *ctx = (drawContext*)context; getPoint(0, 0, p); glRasterPos3d(p[0], p[1], p[2]); ctx->drawString("(X0, Y0, Z0)"); if(getNbU() > 1){ getPoint(getNbU() - 1, 0, p); glRasterPos3d(p[0], p[1], p[2]); ctx->drawString("(X1, Y1, Z1)"); } if(getNbV() > 1){ getPoint(0, getNbV() - 1, p); glRasterPos3d(p[0], p[1], p[2]); ctx->drawString("(X2, Y2, Z2)"); } if(CutGridOptions_Number[11].def){ glBegin(GL_LINES); for(int i = 0; i < getNbU(); ++i){ getPoint(i, 0, p); glVertex3d(p[0], p[1], p[2]); getPoint(i, getNbV()-1, p); glVertex3d(p[0], p[1], p[2]); } for(int i = 0; i < getNbV(); ++i){ getPoint(0, i, p); glVertex3d(p[0], p[1], p[2]); getPoint(getNbU()-1, i, p); glVertex3d(p[0], p[1], p[2]); } glEnd(); } else{ for(int i = 0; i < getNbU(); ++i){ for(int j = 0; j < getNbV(); ++j){ getPoint(i, j, p); ctx->drawSphere(CTX::instance()->pointSize, p[0], p[1], p[2], 1); } } } #endif }
void GMSH_ParticlesPlugin::draw(void *context) { #if defined(HAVE_OPENGL) glColor4ubv((GLubyte *) & CTX::instance()->color.fg); drawContext *ctx = (drawContext*)context; double p[3]; for(int i = 0; i < getNbU(); ++i){ for(int j = 0; j < getNbV(); ++j){ getPoint(i, j, p); ctx->drawSphere(CTX::instance()->pointSize, p[0], p[1], p[2], 1); } } #endif }
PView *GMSH_CutGridPlugin::GenerateView(PView *v1, int connect) { if(getNbU() <= 0 || getNbV() <= 0) return v1; PViewData *data1 = getPossiblyAdaptiveData(v1); PView *v2 = new PView(); PViewDataList *data2 = getDataList(v2); OctreePost o(v1); int nbs = data1->getNumScalars(); int nbv = data1->getNumVectors(); int nbt = data1->getNumTensors(); int maxcomp = nbt ? 9 : (nbv ? 3 : 1); int numsteps = data1->getNumTimeSteps(); double ***pnts = new double** [getNbU()]; double ***vals = new double** [getNbU()]; for(int i = 0; i < getNbU(); i++){ pnts[i] = new double* [getNbV()]; vals[i] = new double* [getNbV()]; for(int j = 0; j < getNbV(); j++){ pnts[i][j] = new double[3]; vals[i][j] = new double[maxcomp * numsteps]; getPoint(i, j, pnts[i][j]); } } if(nbs){ for(int i = 0; i < getNbU(); i++) for(int j = 0; j < getNbV(); j++) o.searchScalar(pnts[i][j][0], pnts[i][j][1], pnts[i][j][2], vals[i][j]); addInView(numsteps, connect, 1, pnts, vals, data2->SP, &data2->NbSP, data2->SL, &data2->NbSL, data2->SQ, &data2->NbSQ); } if(nbv){ for(int i = 0; i < getNbU(); i++) for(int j = 0; j < getNbV(); j++) o.searchVector(pnts[i][j][0], pnts[i][j][1], pnts[i][j][2], vals[i][j]); addInView(numsteps, connect, 3, pnts, vals, data2->VP, &data2->NbVP, data2->VL, &data2->NbVL, data2->VQ, &data2->NbVQ); } if(nbt){ for(int i = 0; i < getNbU(); i++) for(int j = 0; j < getNbV(); j++) o.searchTensor(pnts[i][j][0], pnts[i][j][1], pnts[i][j][2], vals[i][j]); addInView(numsteps, connect, 9, pnts, vals, data2->TP, &data2->NbTP, data2->TL, &data2->NbTL, data2->TQ, &data2->NbTQ); } for(int i = 0; i < getNbU(); i++){ for(int j = 0; j < getNbV(); j++){ delete [] pnts[i][j]; delete [] vals[i][j]; } delete [] pnts[i]; delete [] vals[i]; } delete [] pnts; delete [] vals; data2->setName(data1->getName() + "_CutGrid"); data2->setFileName(data1->getName() + "_CutGrid.pos"); data2->finalize(); return v2; }
void GMSH_CutGridPlugin::addInView(int numsteps, int connect, int nbcomp, double ***pnts, double ***vals, std::vector<double> &P, int *nP, std::vector<double> &L, int *nL, std::vector<double> &Q, int *nQ) { if(!connect || (getNbU() == 1 && getNbV() == 1)){ // generate points for(int i = 0; i < getNbU(); ++i){ for(int j = 0; j < getNbV(); ++j){ P.push_back(pnts[i][j][0]); P.push_back(pnts[i][j][1]); P.push_back(pnts[i][j][2]); (*nP)++; for(int k = 0; k < numsteps; ++k){ for(int l = 0; l < nbcomp; ++l) P.push_back(vals[i][j][nbcomp*k+l]); } } } } else{ // generate lines or quads if(getNbU() == 1){ for(int i = 0; i < getNbV()-1; ++i){ L.push_back(pnts[0][i][0]); L.push_back(pnts[0][i+1][0]); L.push_back(pnts[0][i][1]); L.push_back(pnts[0][i+1][1]); L.push_back(pnts[0][i][2]); L.push_back(pnts[0][i+1][2]); (*nL)++; for(int k = 0; k < numsteps; ++k){ for(int l = 0; l < nbcomp; ++l) L.push_back(vals[0][i ][nbcomp*k+l]); for(int l = 0; l < nbcomp; ++l) L.push_back(vals[0][i+1][nbcomp*k+l]); } } } else if(getNbV() == 1){ for(int i = 0; i < getNbU()-1; ++i){ L.push_back(pnts[i][0][0]); L.push_back(pnts[i+1][0][0]); L.push_back(pnts[i][0][1]); L.push_back(pnts[i+1][0][1]); L.push_back(pnts[i][0][2]); L.push_back(pnts[i+1][0][2]); (*nL)++; for(int k = 0; k < numsteps; ++k){ for(int l = 0; l < nbcomp; ++l) L.push_back(vals[i ][0][nbcomp*k+l]); for(int l = 0; l < nbcomp; ++l) L.push_back(vals[i+1][0][nbcomp*k+l]); } } } else{ for(int i = 0; i < getNbU()-1; ++i){ for(int j = 0; j < getNbV()-1; ++j){ Q.push_back(pnts[i ][j ][0]); Q.push_back(pnts[i+1][j ][0]); Q.push_back(pnts[i+1][j+1][0]); Q.push_back(pnts[i ][j+1][0]); Q.push_back(pnts[i ][j ][1]); Q.push_back(pnts[i+1][j ][1]); Q.push_back(pnts[i+1][j+1][1]); Q.push_back(pnts[i ][j+1][1]); Q.push_back(pnts[i ][j ][2]); Q.push_back(pnts[i+1][j ][2]); Q.push_back(pnts[i+1][j+1][2]); Q.push_back(pnts[i ][j+1][2]); (*nQ)++; for(int k = 0; k < numsteps; ++k){ for(int l = 0; l < nbcomp; ++l) Q.push_back(vals[i ][j ][nbcomp*k+l]); for(int l = 0; l < nbcomp; ++l) Q.push_back(vals[i+1][j ][nbcomp*k+l]); for(int l = 0; l < nbcomp; ++l) Q.push_back(vals[i+1][j+1][nbcomp*k+l]); for(int l = 0; l < nbcomp; ++l) Q.push_back(vals[i ][j+1][nbcomp*k+l]); } } } } } }
PView *GMSH_ParticlesPlugin::execute(PView *v) { double A2 = ParticlesOptions_Number[11].def; double A1 = ParticlesOptions_Number[12].def; double A0 = ParticlesOptions_Number[13].def; double DT = ParticlesOptions_Number[14].def; int maxIter = (int)ParticlesOptions_Number[15].def; int timeStep = (int)ParticlesOptions_Number[16].def; int iView = (int)ParticlesOptions_Number[17].def; PView *v1 = getView(iView, v); if(!v1) return v; PViewData *data1 = getPossiblyAdaptiveData(v1); // sanity checks if(timeStep > data1->getNumTimeSteps() - 1){ Msg::Error("Invalid time step (%d) in view[%d]: using 0", v1->getIndex()); timeStep = 0; } OctreePost o1(v1); PView *v2 = new PView(); PViewDataList *data2 = getDataList(v2); // solve 'A2 d^2x/dt^2 + A1 dx/dt + A0 x = F' using a Newmark scheme: // // (A2 + gamma DT A1 + beta DT^2 A0) x^{n+1} = // (2 A2 - (1 - 2 gamma) DT A1 - (0.5 + gamma - 2 beta) DT^2 A0) x^n + // (-A2 - (gamma - 1) DT A1 - (0.5 - gamma + beta) DT^2 A0) x^{n-1} + // DT^2 (beta b^{n+1} + (0.5 + gamma - 2 beta) b^n + (0.5 - gamma + beta) b^{n-1}) // // coefs for constant acceleration (unconditinonally stable) const double gamma = 0.5, beta = 0.25; double c1 = (A2 + gamma * DT * A1 + beta * DT * DT * A0); double c2 = (2 * A2 - (1 - 2 * gamma) * DT * A1 - (0.5 + gamma - 2 * beta) * DT * DT * A0); double c3 = (-A2 - (gamma - 1) * DT * A1 - (0.5 - gamma + beta) * DT * DT * A0); double c4 = DT * DT * (beta + (0.5 + gamma - 2 * beta) + (0.5 - gamma + beta)); for(int i = 0; i < getNbU(); ++i){ for(int j = 0; j < getNbV(); ++j){ double XINIT[3], X0[3], X1[3]; getPoint(i, j, XINIT); getPoint(i, j, X0); getPoint(i, j, X1); data2->NbVP++; data2->VP.push_back(XINIT[0]); data2->VP.push_back(XINIT[1]); data2->VP.push_back(XINIT[2]); for(int iter = 0; iter < maxIter; iter++){ double F[3], X[3]; o1.searchVector(X1[0], X1[1], X1[2], F, timeStep); for(int k = 0; k < 3; k++) X[k] = (c2 * X1[k] + c3 * X0[k] + c4 * F[k]) / c1; data2->VP.push_back(X[0] - XINIT[0]); data2->VP.push_back(X[1] - XINIT[1]); data2->VP.push_back(X[2] - XINIT[2]); for(int k = 0; k < 3; k++){ X0[k] = X1[k]; X1[k] = X[k]; } } } } v2->getOptions()->vectorType = PViewOptions::Displacement; data2->setName(data1->getName() + "_Particles"); data2->setFileName(data1->getName() + "_Particles.pos"); data2->finalize(); return v2; }