void MovingMeshFB::moveMesh() { int i, j, k, m; double epsilon = 0.2; double error = 1.; double area, h, l[3], d[3]; while (error > epsilon) { getMoveDirection(); error = 0; for (i = 0;i < n_geometry(2);i ++) { const Point<2>& x0 = point(geometry(2,i).vertex(0)); const Point<2>& x1 = point(geometry(2,i).vertex(1)); const Point<2>& x2 = point(geometry(2,i).vertex(2)); l[0] = (x2[0] - x1[0])*(x2[0] - x1[0]) + (x2[1] - x1[1])*(x2[1] - x1[1]); l[1] = (x0[0] - x2[0])*(x0[0] - x2[0]) + (x0[1] - x2[1])*(x0[1] - x2[1]); l[2] = (x1[0] - x0[0])*(x1[0] - x0[0]) + (x1[1] - x0[1])*(x1[1] - x0[1]); area = (x1[0] - x0[0])*(x2[1] - x0[1]) - (x2[0] - x0[0])*(x1[1] - x0[1]); h = 0.5*area/sqrt(*std::max_element(&l[0], &l[3])); for (k = 0;k < 3;++ k) { m = geometry(2,i).vertex(k); for (d[k] = 0.0, j = 0;j < 2;j ++) { d[k] += move_direction[m][j]*move_direction[m][j]; } } h = sqrt(*std::max_element(&d[0], &d[3]))/h; if (error < h) error = h; } std::cerr << "mesh moving error = " << error << std::endl; getMoveStepLength(); for (i = 0;i < n_move_step;i ++) { updateSolution(); updateMesh(); }; }; }
void phgMovingMeshMove(MovingMesh *mmesh, int max_step) { GRID *g = _m->g; FLOAT eps = _mp->tol; FLOAT min_mv = 2 * eps, max_mv = 0.; INT i, j, k, step; FLOAT *v; char name[100]; Unused(j); Unused(k); step = 0; while (min_mv > eps) { if (max_step > 0 && step >= max_step) { phgPrintf(MESSAGE_HEADER1"Moving mesh stop: reach max step\n"); break; } elapsed_time(g, FALSE, 0.); /* reset timer */ if (_mp->verb > 0) { phgPrintf(MESSAGE_HEADER1"Moving mesh substep: %d ", step); elapsed_time(g, TRUE, 0.); } getMoveDirection(mmesh); max_mv = 0; v = _m->move->data; for (i = 0; i < g->nvert; i++) { FLOAT d = 0.; d += *v * *v; v++; d += *v * *v; v++; d += *v * *v; v++; d = sqrt(d); min_mv = MIN(min_mv, d); max_mv = MAX(max_mv, d); } #if USE_MPI { FLOAT min_mv0 = min_mv, max_mv0 = max_mv; MPI_Allreduce(&min_mv0, &min_mv, 1, MPI_DOUBLE, MPI_MIN, g->comm); MPI_Allreduce(&max_mv0, &max_mv, 1, MPI_DOUBLE, MPI_MAX, g->comm); } #endif /* USE_MPI */ if (_mp->verb > 0) { phgPrintf(MESSAGE_HEADER1"mesh moving min move = %e\n", min_mv); phgPrintf(MESSAGE_HEADER1"mesh moving max move = %e\n", max_mv); } getMoveStepLength(_m); for (i = 0;i < _mp->n_move_substep;i ++) { updateDof(_m); updateMesh(_m); #if 1 /* use analytic dof to check update dof */ { DOF **dofs = _m->dofs; //char name[100]; //static int n = 0; DOF *dof_err = phgDofCopy(dofs[0], NULL, NULL, "dof err"); assert(dofs[1]->type == DOF_ANALYTIC); phgDofAXPY(-1.0, dofs[1], &dof_err); phgPrintf("* update dofs change = %e\n", phgDofNormL2(dof_err)); //sprintf(name, "dof_error2_%03d.vtk", n++); //phgExportVTK(g, name, dof_err, NULL); phgDofFree(&dof_err); } #endif /* Check dof update */ } #if 1 sprintf(name, "Moving_mesh.dof_%03d.plt", step); //phgExportVTK(g, name, _m->dofs[0], NULL); //phgExportTecplot(g, name, _m->dofs[0], NULL); //phgExportEnsight(g, "Moving", (double)step, _m->monitor, _m->dofs[0], NULL); #endif /* export dof to VTK files */ step++; } return; }