IntegrationGrid createGrid(char* fname) { std::ifstream in(fname); IntegrationGrid grid; int numIntervals; double xLow, xHigh; while (in >> numIntervals >> xLow >> xHigh) { IntegrationGrid newGrid(numIntervals, xLow, xHigh); grid.makeUnion(newGrid); } in.close(); return grid; }
template <int dim> void update(grid<dim, sparse<phi_type> >& oldGrid, int steps) { int rank=0; #ifdef MPI_VERSION rank=MPI::COMM_WORLD.Get_rank(); #endif const phi_type dt = 0.01; const phi_type width = 14.5; const phi_type epsilon = 1.0e-8; const double mu_hi = 1.00; const double mu_lo = 0.01; const double mu_x = 0.6422; const double mu_s = 0.0175; std::ofstream vfile; if (rank==0) vfile.open("v.log",std::ofstream::out | std::ofstream::app); for (int step = 0; step < steps; step++) { if (rank==0) print_progress(step, steps); // newGrid grid must be overwritten each time ghostswap(oldGrid); grid<dim, sparse<phi_type> > newGrid(oldGrid); for (int d=0; d<dim; d++) { if (x0(oldGrid, d) == g0(oldGrid,d)) { b0(oldGrid,d) = Dirichlet; b0(newGrid,d) = Dirichlet; } else if (x1(oldGrid,d) == g1(oldGrid,d)) { b1(oldGrid,d) = Dirichlet; b1(newGrid,d) = Dirichlet; } } for (int i = 0; i < nodes(oldGrid); i++) { vector<int> x = position(oldGrid, i); // determine nonzero fields within // the neighborhood of this node // (2 adjacent voxels along each cardinal direction) sparse<int> s; for (int j = 0; j < dim; j++) for (int k = -1; k <= 1; k++) { x[j] += k; for (int h = 0; h < length(oldGrid(x)); h++) { int pindex = index(oldGrid(x), h); set(s, pindex) = 1; } x[j] -= k; } phi_type S = phi_type(length(s)); // if only one field is nonzero, // then copy this node to newGrid if (S < 2.0) newGrid(i) = oldGrid(i); else { // compute laplacian of each field sparse<phi_type> lap = laplacian(oldGrid, i); // compute variational derivatives sparse<phi_type> dFdp; for (int h = 0; h < length(s); h++) { int hindex = index(s, h); for (int j = h + 1; j < length(s); j++) { int jindex = index(s, j); phi_type gamma = energy(hindex, jindex); phi_type eps = 4.0 / acos(-1.0) * sqrt(0.5 * gamma * width); phi_type w = 4.0 * gamma / width; // Update dFdp_h and dFdp_j, so the inner loop can be over j>h instead of j≠h set(dFdp, hindex) += 0.5 * eps * eps * lap[jindex] + w * oldGrid(i)[jindex]; set(dFdp, jindex) += 0.5 * eps * eps * lap[hindex] + w * oldGrid(i)[hindex]; } } // compute time derivatives sparse<phi_type> dpdt; phi_type mu = mobility(mu_lo, mu_hi, mu_x, mu_s, oldGrid(x).getMagPhi()); for (int h = 0; h < length(s); h++) { int hindex = index(s, h); for (int j = h + 1; j < length(s); j++) { int jindex = index(s, j); set(dpdt, hindex) -= mu * (dFdp[hindex] - dFdp[jindex]); set(dpdt, jindex) -= mu * (dFdp[jindex] - dFdp[hindex]); } } // compute update values phi_type sum = 0.0; for (int h = 0; h < length(s); h++) { int pindex = index(s, h); phi_type value = oldGrid(i)[pindex] + dt * (2.0 / S) * dpdt[pindex]; // Extraneous factor of 2? if (value > 1.0) value = 1.0; if (value < 0.0) value = 0.0; if (value > epsilon) set(newGrid(i), pindex) = value; sum += newGrid(i)[pindex]; } // project onto Gibbs simplex (enforce Σφ=1) phi_type rsum = 0.0; if (fabs(sum) > 0.0) rsum = 1.0 / sum; for (int h = 0; h < length(newGrid(i)); h++) { int pindex = index(newGrid(i), h); set(newGrid(i), pindex) *= rsum; } } } // Loop over nodes(oldGrid) if ((step+1) % 10 == 0) { // Scan along just above the mid-line for the grain boundary. // When found, determine its angle. vector<int> x(dim, 0); const int offset = 2; const phi_type vert_mag = 1.0/std::sqrt(3.0); const phi_type edge_mag = 1.0/std::sqrt(2.0); const phi_type bulk_mag = 1.0; const phi_type edge_contour = edge_mag + 0.125*(bulk_mag - edge_mag); const phi_type vert_contour = vert_mag + 0.125*(edge_mag - vert_mag); x[0] = x0(newGrid,0); x[1] = (g1(newGrid,1) - g0(newGrid,1))/2; while (x[0]<x1(newGrid) && x[1]>=y0(newGrid) && x[1]<y1(newGrid) && newGrid(x).getMagPhi()>vert_contour) x[0]++; if (x[0] == x1(newGrid)) x[0] = g0(newGrid,0); int v0 = x[0]; #ifdef MPI_VERSION MPI::COMM_WORLD.Allreduce(&x[0], &v0, 1, MPI_INT, MPI_MAX); #endif x[1] += offset; while (x[0]>= x0(newGrid) && x[0]<x1(newGrid) && x[1]>=y0(newGrid) && x[1]<y1(newGrid) && newGrid(x).getMagPhi()>edge_contour) x[0]++; if (x[0] == x1(newGrid)) x[0] = g0(newGrid,0); int v1 = x[0]; #ifdef MPI_VERSION MPI::COMM_WORLD.Allreduce(&x[0], &v1, 1, MPI_INT, MPI_MAX); #endif x[1] += offset; while (x[0]>= x0(newGrid) && x[0]<x1(newGrid) && x[1]>=y0(newGrid) && x[1]<y1(newGrid) && newGrid(x).getMagPhi()>edge_contour) x[0]++; if (x[0] == x1(newGrid)) x[0] = g0(newGrid,0); int v2 = x[0]; #ifdef MPI_VERSION MPI::COMM_WORLD.Allreduce(&x[0], &v2, 1, MPI_INT, MPI_MAX); #endif // Second-order right-sided difference to approximate slope double diffX = 3.0*v0 - 4.0*v1 + 1.0*v2; double theta = 180.0/M_PI * std::atan2(2.0*offset*dx(newGrid,1), dx(newGrid,0)*diffX); if (rank==0) vfile << dx(newGrid,0)*v0 << '\t' << dx(newGrid,0)*v1 << '\t' << dx(newGrid,0)*v2 << '\t' << diffX << '\t' << theta << '\n'; } swap(oldGrid, newGrid); } // Loop over steps ghostswap(oldGrid); if (rank==0) vfile.close(); }
MainWindow::MainWindow(const QString& initialFilename, QWidget *parent) : QMainWindow(parent), m_appSettings("OpenSource", "Sproxel"), m_activeFilename(""), m_project(new SproxelProject()) { // Project VoxelGridGroupPtr sprite(new VoxelGridGroup(Imath::V3i(DEFAULT_VOXGRID_SZ, DEFAULT_VOXGRID_SZ, DEFAULT_VOXGRID_SZ), ColorPalettePtr())); sprite->setName("unnamed"); m_project->sprites.push_back(sprite); // Windows m_glModelWidget = new GLModelWidget(this, &m_appSettings, &m_undoManager, sprite); setCentralWidget(m_glModelWidget); // The docking palette widget m_paletteDocker = new QDockWidget(tr("Palette"), this); m_paletteDocker->setObjectName("paletteDocker"); m_paletteDocker->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); m_paletteWidget = new PaletteWidget(this, &m_undoManager); m_paletteDocker->setWidget(m_paletteWidget); m_paletteWidget->setPalette(m_project->mainPalette); addDockWidget(Qt::RightDockWidgetArea, m_paletteDocker); // The docking project widget m_projectDocker=new QDockWidget(tr("Project"), this); m_projectDocker->setObjectName("projectDocker"); m_projectWidget=new ProjectWidget(this, &m_undoManager, &m_appSettings); m_projectDocker->setWidget(m_projectWidget); m_projectWidget->setProject(m_project); addDockWidget(Qt::RightDockWidgetArea, m_projectDocker); // The docking layers widget //m_layersDocker = new QDockWidget(tr("Layers"), this); //m_layersDocker->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); //m_layersWidget = new LayersWidget(this); //m_layersDocker->setWidget(m_layersWidget); //addDockWidget(Qt::RightDockWidgetArea, m_layersDocker); // Connect some window signals together QObject::connect(m_paletteWidget, SIGNAL(activeColorChanged(Imath::Color4f, int)), m_glModelWidget, SLOT(setActiveColor(Imath::Color4f, int))); QObject::connect(m_glModelWidget, SIGNAL(colorSampled(Imath::Color4f, int)), m_paletteWidget, SLOT(setActiveColor(Imath::Color4f, int))); QObject::connect(&m_undoManager, SIGNAL(cleanChanged(bool)), this, SLOT(reactToModified(bool))); QObject::connect(m_projectWidget, SIGNAL(spriteSelected(VoxelGridGroupPtr)), m_glModelWidget, SLOT(setSprite(VoxelGridGroupPtr))); // Toolbar m_toolbar = new QToolBar("Tools", this); m_toolbar->setObjectName("toolbar"); m_toolbar->setOrientation(Qt::Vertical); addToolBar(Qt::LeftToolBarArea, m_toolbar); // Actions & Menus menuBar()->show(); m_menuFile = menuBar()->addMenu("Fi&le"); m_actFileNew = new QAction("&New", this); m_actFileNew->setShortcut(Qt::CTRL + Qt::Key_N); m_menuFile->addAction(m_actFileNew); connect(m_actFileNew, SIGNAL(triggered()), this, SLOT(newGrid())); m_menuFile->addSeparator(); m_actFileOpen = new QAction("&Open", this); m_actFileOpen->setShortcut(Qt::CTRL + Qt::Key_O); m_menuFile->addAction(m_actFileOpen); connect(m_actFileOpen, SIGNAL(triggered()), this, SLOT(openFile())); m_actFileSave = new QAction("&Save", this); m_actFileSave->setShortcut(Qt::CTRL + Qt::Key_S); m_menuFile->addAction(m_actFileSave); connect(m_actFileSave, SIGNAL(triggered()), this, SLOT(saveFile())); m_actFileSaveAs = new QAction("Save &As", this); m_menuFile->addAction(m_actFileSaveAs); connect(m_actFileSaveAs, SIGNAL(triggered()), this, SLOT(saveFileAs())); m_menuFile->addSeparator(); m_actFileImport = new QAction("&Import...", this); m_menuFile->addAction(m_actFileImport); connect(m_actFileImport, SIGNAL(triggered()), this, SLOT(import())); m_actFileExportGrid = new QAction("&Export...", this); m_menuFile->addAction(m_actFileExportGrid); connect(m_actFileExportGrid, SIGNAL(triggered()), this, SLOT(exportGrid())); m_menuFile->addSeparator(); m_actQuit = new QAction("&Quit", this); m_actQuit->setShortcut(Qt::CTRL + Qt::Key_Q); m_menuFile->addAction(m_actQuit); connect(m_actQuit, SIGNAL(triggered()), this, SLOT(close())); // ------ edit menu m_menuEdit = menuBar()->addMenu("&Edit"); m_actUndo=m_undoManager.createUndoAction(this, "Undo"); m_actUndo->setShortcut(Qt::CTRL + Qt::Key_Z); m_menuEdit->addAction(m_actUndo); m_actRedo=m_undoManager.createRedoAction(this, "Redo"); m_actRedo->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_Z); m_menuEdit->addAction(m_actRedo); m_menuEdit->addSeparator(); m_actShiftUp = new QAction("Shift up", this); m_actShiftUp->setShortcut(Qt::CTRL + Qt::Key_BracketRight); m_menuEdit->addAction(m_actShiftUp); connect(m_actShiftUp, SIGNAL(triggered()), this, SLOT(shiftUp())); m_actShiftDown = new QAction("Shift down", this); m_actShiftDown->setShortcut(Qt::CTRL + Qt::Key_BracketLeft); m_menuEdit->addAction(m_actShiftDown); connect(m_actShiftDown, SIGNAL(triggered()), this, SLOT(shiftDown())); m_actShiftWrap = new QAction("Wrap shift ops", this); m_actShiftWrap->setCheckable(true); m_actShiftWrap->setChecked(m_glModelWidget->shiftWrap()); m_menuEdit->addAction(m_actShiftWrap); connect(m_actShiftWrap, SIGNAL(toggled(bool)), m_glModelWidget, SLOT(setShiftWrap(bool))); m_actRotateCw = new QAction("Rotate clockwise", this); m_actRotateCw->setShortcut(Qt::CTRL + Qt::Key_Greater); m_menuEdit->addAction(m_actRotateCw); connect(m_actRotateCw, SIGNAL(triggered()), this, SLOT(rotateCw())); m_actRotateCcw = new QAction("Rotate counter-clockwise", this); m_actRotateCcw->setShortcut(Qt::CTRL + Qt::Key_Less); m_menuEdit->addAction(m_actRotateCcw); connect(m_actRotateCcw, SIGNAL(triggered()), this, SLOT(rotateCcw())); m_actMirror = new QAction("Mirror", this); m_actMirror->setShortcut(Qt::CTRL + Qt::Key_M); m_menuEdit->addAction(m_actMirror); connect(m_actMirror, SIGNAL(triggered()), this, SLOT(mirror())); m_menuEdit->addSeparator(); m_actPreferences = new QAction("Preferences...", this); m_menuEdit->addAction(m_actPreferences); connect(m_actPreferences, SIGNAL(triggered()), this, SLOT(editPreferences())); // ------ grid menu m_menuGrid = menuBar()->addMenu("&Grid"); m_actExtendUp = new QAction("Extend grid dimension up", this); m_actExtendUp->setShortcut(Qt::CTRL + Qt::Key_Plus); m_menuGrid->addAction(m_actExtendUp); connect(m_actExtendUp, SIGNAL(triggered()), this, SLOT(extendUp())); m_actExtendDown = new QAction("Extend grid dimension down", this); m_actExtendDown->setShortcut(Qt::CTRL + Qt::Key_Minus); m_menuGrid->addAction(m_actExtendDown); connect(m_actExtendDown, SIGNAL(triggered()), this, SLOT(extendDown())); m_actContractUp = new QAction("Contract grid dimension from above", this); m_menuGrid->addAction(m_actContractUp); connect(m_actContractUp, SIGNAL(triggered()), this, SLOT(contractUp())); m_actContractDown = new QAction("Contract grid dimension from below", this); m_menuGrid->addAction(m_actContractDown); connect(m_actContractDown, SIGNAL(triggered()), this, SLOT(contractDown())); m_menuGrid->addSeparator(); m_actUpRes = new QAction("Double grid resolution", this); m_menuGrid->addAction(m_actUpRes); connect(m_actUpRes, SIGNAL(triggered()), this, SLOT(upRes())); m_actDownRes = new QAction("Half grid resolution", this); m_menuGrid->addAction(m_actDownRes); connect(m_actDownRes, SIGNAL(triggered()), this, SLOT(downRes())); // ------ view menu m_menuView = menuBar()->addMenu("&View"); QAction *action=new QAction(tr("Frame sprite"), this); action->setShortcut(Qt::Key_Z); m_menuView->addAction(action); connect(action, SIGNAL(triggered()), m_glModelWidget, SLOT(frameFull())); m_actViewGrid = new QAction("View Grid", this); m_actViewGrid->setShortcut(Qt::CTRL + Qt::Key_G); m_actViewGrid->setCheckable(true); m_actViewGrid->setChecked(m_glModelWidget->drawGrid()); m_menuView->addAction(m_actViewGrid); connect(m_actViewGrid, SIGNAL(toggled(bool)), m_glModelWidget, SLOT(setDrawGrid(bool))); m_actViewVoxgrid = new QAction("Voxel Grid", this); m_actViewVoxgrid->setShortcut(Qt::Key_G); m_actViewVoxgrid->setCheckable(true); m_actViewVoxgrid->setChecked(m_glModelWidget->drawVoxelGrid()); m_menuView->addAction(m_actViewVoxgrid); connect(m_actViewVoxgrid, SIGNAL(toggled(bool)), m_glModelWidget, SLOT(setDrawVoxelGrid(bool))); m_actViewBBox = new QAction("Bounding Box", this); m_actViewBBox->setShortcut(Qt::CTRL + Qt::Key_B); m_actViewBBox->setCheckable(true); m_actViewBBox->setChecked(m_glModelWidget->drawBoundingBox()); m_menuView->addAction(m_actViewBBox); connect(m_actViewBBox, SIGNAL(toggled(bool)), m_glModelWidget, SLOT(setDrawBoundingBox(bool))); action=new QAction("Sprite Bounds", this); action->setShortcut(Qt::Key_B); action->setCheckable(true); action->setChecked(m_glModelWidget->drawSpriteBounds()); m_menuView->addAction(action); connect(action, SIGNAL(toggled(bool)), m_glModelWidget, SLOT(setDrawSpriteBounds(bool))); // ------ window menu m_menuWindow = menuBar()->addMenu("&Window"); m_menuWindow->addAction(m_toolbar->toggleViewAction()); m_menuWindow->addAction(m_paletteDocker->toggleViewAction()); m_menuWindow->addAction(m_projectDocker->toggleViewAction()); //m_menuWindow->addAction(m_layersDocker->toggleViewAction()); m_menuWindow->addAction(get_python_console_widget()->toggleViewAction()); get_python_console_widget()->toggleViewAction()->setChecked(false); // ------ toolbar hookups // Icons from the brilliant icon pack located at : http://pen-art.ru/ m_toolbarActionGroup = new QActionGroup(this); m_actToolSplat = new QAction("Splat", m_toolbarActionGroup); m_actToolSplat->setIcon(QIcon(QPixmap(":/icons/splat.png"))); m_actToolSplat->setCheckable(true); connect(m_actToolSplat, SIGNAL(toggled(bool)), this, SLOT(setToolSplat(bool))); m_actToolReplace = new QAction("Replace", m_toolbarActionGroup); m_actToolReplace->setIcon(QIcon(QPixmap(":/icons/pencil.png"))); m_actToolReplace->setCheckable(true); connect(m_actToolReplace, SIGNAL(toggled(bool)), this, SLOT(setToolReplace(bool))); m_actToolFlood = new QAction("Flood", m_toolbarActionGroup); m_actToolFlood->setIcon(QIcon(QPixmap(":/icons/paintBucket.png"))); m_actToolFlood->setCheckable(true); connect(m_actToolFlood, SIGNAL(toggled(bool)), this, SLOT(setToolFlood(bool))); m_actToolDropper = new QAction("Dropper", m_toolbarActionGroup); m_actToolDropper->setIcon(QIcon(QPixmap(":/icons/eyeDropper.png"))); m_actToolDropper->setCheckable(true); connect(m_actToolDropper, SIGNAL(toggled(bool)), this, SLOT(setToolDropper(bool))); m_actToolEraser = new QAction("Eraser", m_toolbarActionGroup); m_actToolEraser->setIcon(QIcon(QPixmap(":/icons/eraser.png"))); m_actToolEraser->setCheckable(true); connect(m_actToolEraser, SIGNAL(toggled(bool)), this, SLOT(setToolEraser(bool))); m_actToolSlab = new QAction("Slab", m_toolbarActionGroup); m_actToolSlab->setIcon(QIcon(QPixmap(":/icons/slab.png"))); m_actToolSlab->setCheckable(true); connect(m_actToolSlab, SIGNAL(toggled(bool)), this, SLOT(setToolSlab(bool))); m_actToolLine = new QAction("Line", m_toolbarActionGroup); m_actToolLine->setIcon(QIcon(QPixmap(":/icons/line.png"))); m_actToolLine->setCheckable(true); connect(m_actToolLine, SIGNAL(toggled(bool)), this, SLOT(setToolLine(bool))); m_actToolBox = new QAction("Box", m_toolbarActionGroup); m_actToolBox->setIcon(QIcon(QPixmap(":/icons/box.png"))); m_actToolBox->setCheckable(true); connect(m_actToolBox, SIGNAL(toggled(bool)), this, SLOT(setToolBox(bool))); m_actToolExtrude = new QAction("Extrude", m_toolbarActionGroup); m_actToolExtrude->setIcon(QIcon(QPixmap(":/icons/extrude.png"))); m_actToolExtrude->setCheckable(true); connect(m_actToolExtrude, SIGNAL(toggled(bool)), this, SLOT(setToolExtrude(bool))); //m_actToolRay = new QAction("Ray", this); m_actToolSplat->setChecked(true); m_toolbar->addActions(m_toolbarActionGroup->actions()); // Toolbar widgets for slicing m_toolbar->addSeparator(); m_minSliceBox=new QSpinBox(); m_maxSliceBox=new QSpinBox(); m_toolbar->addWidget(m_maxSliceBox); m_toolbar->addWidget(m_minSliceBox); connect(m_glModelWidget, SIGNAL(sliceChanged(int, int, int)), this, SLOT(updateSlice(int, int, int))); connect(m_minSliceBox, SIGNAL(valueChanged(int)), m_glModelWidget, SLOT(setMinSlice(int))); connect(m_maxSliceBox, SIGNAL(valueChanged(int)), m_glModelWidget, SLOT(setMaxSlice(int))); // axis selection QActionGroup *axisGroup=new QActionGroup(this); QAction *a=new QAction("X", axisGroup); a->setCheckable(true); connect(a, SIGNAL(toggled(bool)), m_glModelWidget, SLOT(setAxisX())); m_actAxisX=a; a=new QAction("Y", axisGroup); a->setCheckable(true); connect(a, SIGNAL(toggled(bool)), m_glModelWidget, SLOT(setAxisY())); m_actAxisY=a; a=new QAction("Z", axisGroup); a->setCheckable(true); connect(a, SIGNAL(toggled(bool)), m_glModelWidget, SLOT(setAxisZ())); m_actAxisZ=a; m_toolbar->addSeparator(); m_toolbar->addActions(axisGroup->actions()); m_actAxisY->setChecked(true); // Remaining verbosity setWindowTitle(BASE_WINDOW_TITLE); statusBar()->showMessage(tr("Ready")); // Load up some settings if (m_appSettings.value("saveUILayout", true).toBool()) { resize(m_appSettings.value("MainWindow/size", QSize(546, 427)).toSize()); move(m_appSettings.value("MainWindow/position", QPoint(200, 200)).toPoint()); setWindowState((Qt::WindowStates)m_appSettings.value("MainWindow/windowState", Qt::WindowActive).toInt()); restoreState(m_appSettings.value("MainWindow/widgetsState").toByteArray()); m_toolbar->setVisible(m_appSettings.value("toolbar/visibility", true).toBool()); m_paletteDocker->setVisible(m_appSettings.value("paletteWindow/visibility", true).toBool()); m_projectDocker->setVisible(m_appSettings.value("projectWindow/visibility", true).toBool()); //m_layersDocker->setVisible(m_appSettings.value("layersWindow/visibility", true).toBool()); } // Load the commandline supplied filename if (initialFilename != "") { openFile(initialFilename); } // Better way to keep the state in one place //std::cout << (m_toolbarActionGroup->checkedAction()->text() == "Splat") << std::endl; //std::cout << qPrintable(m_toolbarActionGroup->checkedAction()->text()) << std::endl; // Start things off focused on the GLWidget m_glModelWidget->setFocus(); }
template <int dim> void update(grid<dim, sparse<phi_type> >& oldGrid, int steps) { #if (!defined MPI_VERSION) && (defined BGQ) std::cerr<<"Error: Blue Gene requires MPI."<<std::endl; exit(-1); #endif int rank=0; #ifdef MPI_VERSION rank = MPI::COMM_WORLD.Get_rank(); #endif const phi_type dt = 0.01; const phi_type width = 14.5; const phi_type epsilon = 1.0e-8; for (int step = 0; step < steps; step++) { if (rank==0) print_progress(step, steps); // newGrid must be overwritten each time ghostswap(oldGrid); grid<dim, sparse<phi_type> > newGrid(oldGrid); for (int i = 0; i < nodes(oldGrid); i++) { vector<int> x = position(oldGrid, i); // determine nonzero fields within // the neighborhood of this node // (2 adjacent voxels along each cardinal direction) sparse<int> s; for (int j = 0; j < dim; j++) for (int k = -1; k <= 1; k++) { x[j] += k; for (int h = 0; h < length(oldGrid(x)); h++) { int sindex = index(oldGrid(x), h); set(s, sindex) = 1; } x[j] -= k; } phi_type S = phi_type(length(s)); // if only one field is nonzero, // then copy this node to newGrid if (S < 2.0) newGrid(i) = oldGrid(i); else { // compute laplacian of each field sparse<phi_type> lap = laplacian(oldGrid, i); // compute variational derivatives sparse<phi_type> dFdp; for (int h = 0; h < length(s); h++) { int hindex = index(s, h); for (int j = h + 1; j < length(s); j++) { int jindex = index(s, j); phi_type gamma = energy(hindex, jindex); phi_type eps = 4.0 / acos(-1.0) * sqrt(0.5 * gamma * width); phi_type w = 4.0 * gamma / width; // Update dFdp_h and dFdp_j, so the inner loop can be over j>h instead of j≠h set(dFdp, hindex) += 0.5 * eps * eps * lap[jindex] + w * oldGrid(i)[jindex]; set(dFdp, jindex) += 0.5 * eps * eps * lap[hindex] + w * oldGrid(i)[hindex]; } } // compute time derivatives sparse<phi_type> dpdt; for (int h = 0; h < length(s); h++) { int hindex = index(s, h); for (int j = h + 1; j < length(s); j++) { int jindex = index(s, j); phi_type mu = mobility(hindex, jindex); set(dpdt, hindex) -= mu * (dFdp[hindex] - dFdp[jindex]); set(dpdt, jindex) -= mu * (dFdp[jindex] - dFdp[hindex]); } } // compute new values phi_type sum = 0.0; for (int h = 0; h < length(s); h++) { int sindex = index(s, h); phi_type value = oldGrid(i)[sindex] + dt * (2.0 / S) * dpdt[sindex]; // Extraneous factor of 2? if (value > 1.0) value = 1.0; if (value < 0.0) value = 0.0; if (value > epsilon) set(newGrid(i), sindex) = value; sum += newGrid(i)[sindex]; } // project onto Gibbs simplex (enforce Σφ=1) phi_type rsum = 0.0; if (fabs(sum) > 0.0) rsum = 1.0 / sum; for (int h = 0; h < length(newGrid(i)); h++) { int sindex = index(newGrid(i), h); set(newGrid(i), sindex) *= rsum; } } } // Loop over nodes(oldGrid) swap(oldGrid, newGrid); } // Loop over steps ghostswap(oldGrid); }
virtual QSharedPointer< Grid<T> > clone() { QSharedPointer< Grid<T> > newGrid( new WrapHexGrid<T>( this->size() ) ); newGrid->setItems( this->items() ); return newGrid; }
const GridPtr Board::build(const Pattern pattern) const { GridPtr newGrid(new Grid(boost::extents[30][120])); switch(pattern){ case BLINKER: (*newGrid)[15][14] = true; (*newGrid)[15][15] = true; (*newGrid)[15][16] = true; break; case TOAD: (*newGrid)[15][14] = true; (*newGrid)[15][15] = true; (*newGrid)[15][16] = true; (*newGrid)[16][13] = true; (*newGrid)[16][14] = true; (*newGrid)[16][15] = true; break; case ACORN: (*newGrid)[13][26] = true; (*newGrid)[14][28] = true; (*newGrid)[15][25] = true; (*newGrid)[15][26] = true; (*newGrid)[15][29] = true; (*newGrid)[15][30] = true; (*newGrid)[15][31] = true; break; case LINE: (*newGrid)[14][41] = true; (*newGrid)[14][42] = true; (*newGrid)[14][43] = true; (*newGrid)[14][44] = true; (*newGrid)[14][45] = true; (*newGrid)[14][46] = true; (*newGrid)[14][47] = true; (*newGrid)[14][48] = true; (*newGrid)[14][50] = true; (*newGrid)[14][51] = true; (*newGrid)[14][52] = true; (*newGrid)[14][53] = true; (*newGrid)[14][54] = true; (*newGrid)[14][58] = true; (*newGrid)[14][59] = true; (*newGrid)[14][60] = true; (*newGrid)[14][67] = true; (*newGrid)[14][68] = true; (*newGrid)[14][69] = true; (*newGrid)[14][70] = true; (*newGrid)[14][71] = true; (*newGrid)[14][72] = true; (*newGrid)[14][73] = true; (*newGrid)[14][75] = true; (*newGrid)[14][76] = true; (*newGrid)[14][77] = true; (*newGrid)[14][78] = true; (*newGrid)[14][79] = true; break; case GOSPER_GUN: (*newGrid)[6][2] = true; (*newGrid)[6][3] = true; (*newGrid)[7][2] = true; (*newGrid)[7][3] = true; (*newGrid)[6][12] = true; (*newGrid)[7][12] = true; (*newGrid)[8][12] = true; (*newGrid)[5][13] = true; (*newGrid)[9][13] = true; (*newGrid)[4][14] = true; (*newGrid)[4][15] = true; (*newGrid)[10][14] = true; (*newGrid)[10][15] = true; (*newGrid)[7][16] = true; (*newGrid)[5][17] = true; (*newGrid)[9][17] = true; (*newGrid)[6][18] = true; (*newGrid)[7][18] = true; (*newGrid)[8][18] = true; (*newGrid)[7][19] = true; (*newGrid)[4][22] = true; (*newGrid)[5][22] = true; (*newGrid)[6][22] = true; (*newGrid)[4][23] = true; (*newGrid)[5][23] = true; (*newGrid)[6][23] = true; (*newGrid)[3][24] = true; (*newGrid)[7][24] = true; (*newGrid)[2][26] = true; (*newGrid)[3][26] = true; (*newGrid)[7][26] = true; (*newGrid)[8][26] = true; (*newGrid)[4][36] = true; (*newGrid)[5][36] = true; (*newGrid)[4][37] = true; (*newGrid)[5][37] = true; break; default: break; } return newGrid; }
static uiControl *assorted(void) { uiGrid *outergrid; uiGrid *innergrid; uiButton *b; outergrid = newGrid(); innergrid = newGrid(); one = uiNewButton("Test"); uiGridAppend(innergrid, uiControl(one), 1, 1, 1, 1, 0, uiAlignFill, 0, uiAlignFill); hideOne = uiNewButton("Hide One"); uiButtonOnClicked(hideOne, onHideOne, NULL); uiGridAppend(innergrid, uiControl(hideOne), 0, 1, 1, 1, 0, uiAlignFill, 0, uiAlignFill); showOne = uiNewButton("Show One"); uiButtonOnClicked(showOne, onShowOne, NULL); uiGridAppend(innergrid, uiControl(showOne), 2, 1, 1, 1, 0, uiAlignFill, 0, uiAlignFill); b = uiNewButton("Hide All"); uiButtonOnClicked(b, onHideAll, NULL); uiGridAppend(innergrid, uiControl(b), 1, 0, 1, 1, 0, uiAlignFill, 0, uiAlignFill); b = uiNewButton("Show All"); uiButtonOnClicked(b, onShowAll, NULL); uiGridAppend(innergrid, uiControl(b), 1, 2, 1, 1, 0, uiAlignFill, 0, uiAlignFill); uiGridAppend(outergrid, uiControl(innergrid), 0, 0, 1, 1, 1, uiAlignFill, 1, uiAlignFill); innergrid = newGrid(); b = uiNewButton("Insert Trailing"); uiButtonOnClicked(b, onInsertTrailing, innergrid); uiGridAppend(innergrid, uiControl(b), 0, 0, 1, 1, 1, uiAlignFill, 0, uiAlignFill); b = uiNewButton("Insert Bottom"); uiButtonOnClicked(b, onInsertBottom, innergrid); uiGridAppend(innergrid, uiControl(b), 1, 0, 1, 1, 1, uiAlignFill, 0, uiAlignFill); b = uiNewButton("Insert Leading"); uiButtonOnClicked(b, onInsertLeading, innergrid); uiGridAppend(innergrid, uiControl(b), 1, 1, 1, 1, 1, uiAlignFill, 0, uiAlignFill); b = uiNewButton("Insert Top"); uiButtonOnClicked(b, onInsertTop, innergrid); uiGridAppend(innergrid, uiControl(b), 0, 1, 1, 1, 1, uiAlignFill, 0, uiAlignFill); uiGridAppend(outergrid, uiControl(innergrid), 1, 0, 1, 1, 1, uiAlignFill, 1, uiAlignFill); innergrid = newGrid(); uiGridAppend(innergrid, uiControl(uiNewColorButton()), 0, 0, 1, 1, 1, uiAlignFill, 0, uiAlignFill); uiGridAppend(innergrid, uiControl(uiNewColorButton()), 0, 1, 1, 1, 1, uiAlignStart, 0, uiAlignFill); uiGridAppend(innergrid, uiControl(uiNewColorButton()), 0, 2, 1, 1, 1, uiAlignCenter, 0, uiAlignFill); uiGridAppend(innergrid, uiControl(uiNewColorButton()), 0, 3, 1, 1, 1, uiAlignEnd, 0, uiAlignFill); uiGridAppend(outergrid, uiControl(innergrid), 0, 1, 1, 1, 1, uiAlignFill, 1, uiAlignFill); // TODO with only this, wrong size on OS X — expand sizing thing? innergrid = newGrid(); uiGridAppend(innergrid, uiControl(uiNewColorButton()), 0, 0, 1, 1, 0, uiAlignFill, 1, uiAlignFill); uiGridAppend(innergrid, uiControl(uiNewColorButton()), 1, 0, 1, 1, 0, uiAlignFill, 1, uiAlignStart); uiGridAppend(innergrid, uiControl(uiNewColorButton()), 2, 0, 1, 1, 0, uiAlignFill, 1, uiAlignCenter); uiGridAppend(innergrid, uiControl(uiNewColorButton()), 3, 0, 1, 1, 0, uiAlignFill, 1, uiAlignEnd); uiGridAppend(outergrid, uiControl(innergrid), 1, 1, 1, 1, 1, uiAlignFill, 1, uiAlignFill); return uiControl(outergrid); }
std::pair<double, Util::gridconfig_t> GridFitter::GradientDescent::step(candidate_set &bestGrids, Util::gridconfig_t const& config, double error, const GridFitter::GradientDescent::StepParameter param) { // when adjusting one of the position parameters, we can not adjust the step // size based on the difference between of the errors and the learning rate // (because the coordinates are discrete values). // instead, in each step we only change the position by either 1 or -1. // furthermore, if the error does not improve after a position change, // instead of just applying the reverse direction, we check if the error // acutally improves when going in the reverse direction. static const std::array<int, 2> directions {-1, 1}; const double alpha = _settings.alpha; const double eps_scale = _settings.eps_scale; const int eps_pos = _settings.eps_pos; const double eps_angle = _settings.eps_angle; for (int direction : directions) { Util::gridconfig_t newConfig(config); // adjust parameter switch (param) { case SCALE: newConfig.radius = newConfig.radius + direction * eps_scale; break; case POSX: newConfig.center = newConfig.center + cv::Point2i(direction * eps_pos, 0); break; case POSY: newConfig.center = newConfig.center + cv::Point2i(0, direction * eps_pos); break; case ANGLE_X: newConfig.angle_x = newConfig.angle_x + direction * eps_angle; break; case ANGLE_Y: newConfig.angle_y = newConfig.angle_y + direction * eps_angle; break; case ANGLE_Z: newConfig.angle_z = newConfig.angle_z + direction * eps_angle; break; default: assert(false); break; } // TODO: don't construct new Grid in each step PipelineGrid newGrid(newConfig); double newError = evaluateCandidate(newGrid, _roi, _binarizedRoi, _edgeRoiX, _edgeRoiY, _settings); // adjust parameter based on learning rate and new error if (param != POSX && param != POSY) { switch (param) { case SCALE: newConfig.radius = config.radius + direction * alpha * (error - newError); break; case ANGLE_X: newConfig.angle_x = config.angle_x + direction * alpha * (error - newError); break; case ANGLE_Y: newConfig.angle_y = config.angle_y + direction * alpha * (error - newError); break; case ANGLE_Z: newConfig.angle_z = config.angle_z + direction * alpha * (error - newError); break; default: break; } PipelineGrid newGrid(newConfig); newError = evaluateCandidate(newGrid, _roi, _binarizedRoi, _edgeRoiX, _edgeRoiY, _settings); bestGrids.insert({newError, newConfig}); return {newError, newConfig}; } else if (newError < error) { bestGrids.insert({newError, newConfig}); return {newError, newConfig}; } } return {error, config}; }