/// Solve again w/ the specified RHS, put result in specified vector (specialized) void p_resolveImpl(const VectorType& b, VectorType& x) const { PetscErrorCode ierr(0); int me(this->processor_rank()); try { const Vec *bvec(PETScVector(b)); Vec *xvec(PETScVector(x)); ierr = KSPSolve(p_KSP, *bvec, *xvec); CHKERRXX(ierr); int its; KSPConvergedReason reason; PetscReal rnorm; ierr = KSPGetIterationNumber(p_KSP, &its); CHKERRXX(ierr); ierr = KSPGetConvergedReason(p_KSP, &reason); CHKERRXX(ierr); ierr = KSPGetResidualNorm(p_KSP, &rnorm); CHKERRXX(ierr); std::string msg; if (reason < 0) { msg = boost::str(boost::format("%d: PETSc KSP diverged after %d iterations, reason: %d") % me % its % reason); throw Exception(msg); } else if (me == 0) { msg = boost::str(boost::format("%d: PETSc KSP converged after %d iterations, reason: %d") % me % its % reason); std::cerr << msg << std::endl; } } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, e); } catch (const Exception& e) { throw e; } }
void MainWindow::_update_scene_matrix(const QMatrix4x4& mat) { QMatrix4x4 moo; QVector3D eye(sqrt(2.0)*_axis_len/2.0, 0, sqrt(2.0)*_axis_len/2.0); QVector3D center(0,0,0); QVector3D up(0,1,0); //moo.lookAt(eye,center,up); QVector4D xvec(_axis_len,0,0,1); QVector4D yvec(0,_axis_len,0,1); QVector4D zvec(0,0,_axis_len,1); xvec = moo*_mat*xvec; yvec = moo*_mat*yvec; zvec = moo*_mat*zvec; _xitem->setLine(0,0,xvec.x(),-xvec.y()); _yitem->setLine(0,0,yvec.x(),-yvec.y()); _zitem->setLine(0,0,zvec.x(),-zvec.y()); }
bool LinearSolverPCG<MatrixType>::solve(const SparseBlockMatrix<MatrixType>& A, double* x, double* b) { const bool indexRequired = _indices.size() == 0; _diag.clear(); _J.clear(); // put the block matrix once in a linear structure, makes mult faster int colIdx = 0; for (size_t i = 0; i < A.blockCols().size(); ++i){ const typename SparseBlockMatrix<MatrixType>::IntBlockMap& col = A.blockCols()[i]; if (col.size() > 0) { typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it; for (it = col.begin(); it != col.end(); ++it) { if (it->first == (int)i) { // only the upper triangular block is needed _diag.push_back(it->second); _J.push_back(it->second->inverse()); break; } if (indexRequired) { _indices.push_back(std::make_pair(it->first > 0 ? A.rowBlockIndices()[it->first-1] : 0, colIdx)); _sparseMat.push_back(it->second); } } } colIdx = A.colBlockIndices()[i]; } int n = A.rows(); assert(n > 0 && "Hessian has 0 rows/cols"); Eigen::Map<VectorXD> xvec(x, A.cols()); const Eigen::Map<VectorXD> bvec(b, n); xvec.setZero(); VectorXD r, d, q, s; d.setZero(n); q.setZero(n); s.setZero(n); r = bvec; multDiag(A.colBlockIndices(), _J, r, d); double dn = r.dot(d); double d0 = _tolerance * dn; if (_absoluteTolerance) { if (_residual > 0.0 && _residual > d0) d0 = _residual; } int maxIter = _maxIter < 0 ? A.rows() : _maxIter; int iteration; for (iteration = 0; iteration < maxIter; ++iteration) { if (_verbose) std::cerr << "residual[" << iteration << "]: " << dn << std::endl; if (dn <= d0) break; // done mult(A.colBlockIndices(), d, q); double a = dn / d.dot(q); xvec += a*d; // TODO: reset residual here every 50 iterations r -= a*q; multDiag(A.colBlockIndices(), _J, r, s); double dold = dn; dn = r.dot(s); double ba = dn / dold; d = s + ba*d; } //std::cerr << "residual[" << iteration << "]: " << dn << std::endl; _residual = 0.5 * dn; G2OBatchStatistics* globalStats = G2OBatchStatistics::globalStats(); if (globalStats) { globalStats->iterationsLinearSolver = iteration; } return true; }
CString CGenethonDoc::runTest3(PyObject *pModule, CString& function) { CString output = CString(); PyObject *pDict, *pFunc; PyObject *pArgTuple, *pValue, *pXVec, *pYVec; PyObject *ptype, *pvalue, *ptraceback; int i; // Set the path to include the current directory in case the module is located there. Found from // http://stackoverflow.com/questions/7624529/python-c-api-doesnt-load-module // and http://stackoverflow.com/questions/7283964/embedding-python-into-c-importing-modules if (pModule != NULL) { pFunc = PyObject_GetAttrString(pModule, function); //Get the function by its name // pFunc is a new reference if (pFunc && PyCallable_Check(pFunc)) { //Set up a tuple that will contain the function arguments. In this case, the //function requires two tuples, so we set up a tuple of size 2. pArgTuple = PyTuple_New(2); //Make some vectors containing the data static const double xarr[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14 }; std::vector<double> xvec(xarr, xarr + sizeof(xarr) / sizeof(xarr[0])); static const double yarr[] = { 0,0,1,1,0,0,2,2,0,0,1,1,0,0 }; std::vector<double> yvec(yarr, yarr + sizeof(yarr) / sizeof(yarr[0])); //Transfer the C++ vector to a python tuple pXVec = PyTuple_New(xvec.size()); for (i = 0; i < xvec.size(); ++i) { pValue = PyFloat_FromDouble(xvec[i]); if (!pValue) { Py_DECREF(pXVec); Py_DECREF(pModule); return "Cannot convert array value\n"; } PyTuple_SetItem(pXVec, i, pValue); } //Transfer the other C++ vector to a python tuple pYVec = PyTuple_New(yvec.size()); for (i = 0; i < yvec.size(); ++i) { pValue = PyFloat_FromDouble(yvec[i]); if (!pValue) { Py_DECREF(pYVec); Py_DECREF(pModule); return "Cannot convert array value\n"; } PyTuple_SetItem(pYVec, i, pValue); // } //Set the argument tuple to contain the two input tuples PyTuple_SetItem(pArgTuple, 0, pXVec); PyTuple_SetItem(pArgTuple, 1, pYVec); //Call the python function pValue = PyObject_CallObject(pFunc, pArgTuple); Py_DECREF(pArgTuple); // Py_DECREF(pXVec); // Py_DECREF(pYVec); if (pValue != NULL) { PyObject* v = PyObject_GetAttrString(pModule, "richTextOutput"); output.Format("Result of call: %ld", PyLong_AsLong(pValue)); Py_DECREF(pValue); } //Some error catching else { Py_DECREF(pFunc); Py_DECREF(pModule); return handlePyError(); } } else { if (PyErr_Occurred()) { return handlePyError(); } } Py_XDECREF(pFunc); Py_DECREF(pModule); } else { return handlePyError(); } return output; }
// A fill specialized to the single node at the coupling interface void ConvDiff_PDE::computeHeatFlux( const Epetra_Vector * soln ) { int numDep = depProblems.size(); // Create the overlapped solution and position vectors Epetra_Vector u(*OverlapMap); Epetra_Vector uold(*OverlapMap); std::vector<Epetra_Vector*> dep(numDep); for( int i = 0; i < numDep; ++i) dep[i] = new Epetra_Vector(*OverlapMap); Epetra_Vector xvec(*OverlapMap); // Export Solution to Overlap vector // If the vector to be used in the fill is already in the Overlap form, // we simply need to map on-processor from column-space indices to // OverlapMap indices. Note that the old solution is simply fixed data that // needs to be sent to an OverlapMap (ghosted) vector. The conditional // treatment for the current soution vector arises from use of // FD coloring in parallel. uold.Import(*oldSolution, *Importer, Insert); for( int i = 0; i < numDep; ++i ) (*dep[i]).Import(*( (*(depSolutions.find(depProblems[i]))).second ), *Importer, Insert); xvec.Import(*xptr, *Importer, Insert); if( NULL == soln ) u.Import(*initialSolution, *Importer, Insert); else u.Import(*soln, *Importer, Insert); // Declare required variables int row; double * xx = new double[2]; double * uu = new double[2]; double * uuold = new double[2]; std::vector<double*> ddep(numDep); for( int i = 0; i < numDep; ++i) ddep[i] = new double[2]; Basis basis; // Bundle up the dependent variables in the way needed for computing // the source terms of each reaction map<string, double*> depVars; depVars.insert( pair< std::string, double*>(getName(), uu) ); for( int i = 0; i < numDep; ++i ) depVars.insert( pair<string, double*>(myManager->getProblemName(depProblems[i]), ddep[i]) ); myFlux = 0.0; // Loop Over Gauss Points for( int gp = 0; gp < 2; ++gp ) { // Get the solution and coordinates at the nodes xx[0]=xvec[interface_elem]; xx[1]=xvec[interface_elem+1]; uu[0] = u[interface_elem]; uu[1] = u[interface_elem+1]; uuold[0] = uold[interface_elem]; uuold[1] = uold[interface_elem+1]; for( int i = 0; i < numDep; ++i ) { ddep[i][0] = (*dep[i])[interface_elem]; ddep[i][1] = (*dep[i])[interface_elem+1]; } // Calculate the basis function and variables at the gauss points basis.getBasis(gp, xx, uu, uuold, ddep); row = OverlapMap->GID( interface_elem + local_node ); if( StandardMap->MyGID(row) ) { myFlux += + basis.wt * basis.dx * ( peclet * (basis.duu / basis.dx) * basis.phi[local_node] + kappa * (1.0/(basis.dx*basis.dx)) * basis.duu * basis.dphide[local_node] ); } } // Sync up processors to be safe Comm->Barrier(); // Cleanup for( int i = 0; i < numDep; ++i) { delete [] ddep[i]; delete dep[i]; } delete [] xx ; delete [] uu ; delete [] uuold ; //int lastDof = StandardMap->LID(StandardMap->MaxAllGID()); //cout << "\t\"" << myName << "\" u[0] = " << u[0] // << "\tu[N] = " << u[lastDof] << std::endl; //cout << u << std::endl; //cout << "\t\"" << myName << "\" myFlux = " << myFlux << std::endl << std::endl; // Scale domain integration according to interface position myFlux *= dirScale; // Now add radiation contribution to flux myFlux += radiation * ( pow(u[interface_node], 4) - pow(u[opposite_node], 4) ); return; }
// Matrix and Residual Fills bool ConvDiff_PDE::evaluate( NOX::Epetra::Interface::Required::FillType flag, const Epetra_Vector * soln, Epetra_Vector * rhs) { if( rhs == 0 ) { std::string msg = "ERROR: ConvDiff_PDE::evaluate : callback appears to be other than a residual fill. Others are not support for this type."; throw msg; } int numDep = depProblems.size(); // Create the overlapped solution and position vectors Epetra_Vector u(*OverlapMap); Epetra_Vector uold(*OverlapMap); std::vector<Epetra_Vector*> dep(numDep); for( int i = 0; i < numDep; ++i) dep[i] = new Epetra_Vector(*OverlapMap); Epetra_Vector xvec(*OverlapMap); // Export Solution to Overlap vector // If the vector to be used in the fill is already in the Overlap form, // we simply need to map on-processor from column-space indices to // OverlapMap indices. Note that the old solution is simply fixed data that // needs to be sent to an OverlapMap (ghosted) vector. The conditional // treatment for the current soution vector arises from use of // FD coloring in parallel. uold.Import(*oldSolution, *Importer, Insert); for( int i = 0; i < numDep; ++i ) (*dep[i]).Import(*( (*(depSolutions.find(depProblems[i]))).second ), *Importer, Insert); xvec.Import(*xptr, *Importer, Insert); if( flag == NOX::Epetra::Interface::Required::FD_Res) // Overlap vector for solution received from FD coloring, so simply reorder // on processor u.Export(*soln, *ColumnToOverlapImporter, Insert); else // Communication to Overlap vector is needed u.Import(*soln, *Importer, Insert); // Declare required variables int OverlapNumMyNodes = OverlapMap->NumMyElements(); int OverlapMinMyNodeGID; if (MyPID==0) OverlapMinMyNodeGID = StandardMap->MinMyGID(); else OverlapMinMyNodeGID = StandardMap->MinMyGID()-1; int row; double * xx = new double[2]; double * uu = new double[2]; double * uuold = new double[2]; std::vector<double*> ddep(numDep); for( int i = 0; i < numDep; ++i) ddep[i] = new double[2]; Basis basis; // Bundle up the dependent variables in the way needed for computing // the source terms of each reaction map<string, double*> depVars; depVars.insert( pair< std::string, double*>(getName(), uu) ); for( int i = 0; i < numDep; ++i ) depVars.insert( pair<string, double*>(myManager->getProblemName(depProblems[i]), ddep[i]) ); // Zero out the objects that will be filled rhs->PutScalar(0.0); // Loop Over # of Finite Elements on Processor for( int ne = 0; ne < OverlapNumMyNodes-1; ++ne ) { // Loop Over Gauss Points for( int gp = 0; gp < 2; ++gp ) { // Get the solution and coordinates at the nodes xx[0]=xvec[ne]; xx[1]=xvec[ne+1]; uu[0] = u[ne]; uu[1] = u[ne+1]; uuold[0] = uold[ne]; uuold[1] = uold[ne+1]; for( int i = 0; i < numDep; ++i ) { ddep[i][0] = (*dep[i])[ne]; ddep[i][1] = (*dep[i])[ne+1]; } // Calculate the basis function and variables at the gauss points basis.getBasis(gp, xx, uu, uuold, ddep); // Loop over Nodes in Element for( int i = 0; i < 2; ++i ) { row = OverlapMap->GID(ne+i); if( StandardMap->MyGID(row) ) { (*rhs)[StandardMap->LID(OverlapMap->GID(ne+i))] += + basis.wt * basis.dx * ( peclet * (basis.duu / basis.dx) * basis.phi[i] + kappa * (1.0/(basis.dx*basis.dx)) * basis.duu * basis.dphide[i] ); } } } } //if( NOX::Epetra::Interface::Required::Residual == flag ) //{ // int lastDof = StandardMap->LID(StandardMap->MaxAllGID()); // std::cout << "\t\"" << myName << "\" u[0] = " << (*soln)[0] // << "\tu[N] = " << (*soln)[lastDof] << std::endl; // std::cout << "\t\"" << myName << "\" RHS[0] = " << (*rhs)[0] // << "\tRHS[N] = " << (*rhs)[lastDof] << std::endl << std::endl; //} // Apply BCs computeHeatFlux( soln ); double bcResidual = bcWeight * (myFlux - depProbPtr->getHeatFlux() ) - (1.0 - bcWeight) * (u[interface_node] - depProbPtr->getInterfaceTemp() ); int lastDof = StandardMap->LID(StandardMap->MaxAllGID()); // "Left" boundary if( LEFT == myInterface ) // this may break in parallel { (*rhs)[0] = bcResidual; (*rhs)[lastDof] = (*soln)[lastDof] - Tright; } // "Right" boundary else { (*rhs)[0] = (*soln)[0] - Tleft; (*rhs)[lastDof] = bcResidual; } // Sync up processors to be safe Comm->Barrier(); A->FillComplete(); #ifdef DEBUG std::cout << "For residual fill :" << std::endl << *rhs << std::endl; #endif // Cleanup for( int i = 0; i < numDep; ++i) { delete [] ddep[i]; delete dep[i]; } delete [] xx ; delete [] uu ; delete [] uuold ; return true; }
FoMo::RenderCube CGAL2D(FoMo::GoftCube goftcube, const double l, const int x_pixel, const int y_pixel, const int lambda_pixel, const double lambda_width) { // // results is an array of at least dimension (x2-x1+1)*(y2-y1+1)*lambda_pixel and must be initialized to zero // // determine contributions per pixel typedef K::FT Coord_type; typedef K::Point_2 Point; std::map<Point, Coord_type, K::Less_xy_2> peakmap, fwhmmap, losvelmap; // typedef CGAL::Data_access< std::map<Point, Coord_type, K::Less_xyz_3 > > Value_access; int commrank; #ifdef HAVEMPI MPI_Comm_rank(MPI_COMM_WORLD,&commrank); #else commrank = 0; #endif //FoMo::DataCube goftcube=object.datacube; FoMo::tgrid grid = goftcube.readgrid(); int ng=goftcube.readngrid(); // We will calculate the maximum image coordinates by projecting the grid onto the image plane // Rotate the grid over an angle -l (around z-axis), and -b (around y-axis) // Take the min and max of the resulting coordinates, those are coordinates in the image plane if (commrank==0) std::cout << "Rotating coordinates to POS reference... " << std::flush; std::vector<double> xacc, yacc, zacc; xacc.resize(ng); yacc.resize(ng); zacc.resize(ng); std::vector<double> gridpoint; gridpoint.resize(3); Point temporarygridpoint; // Define the unit vector along the line-of-sight: the LOS is along y std::vector<double> unit = {cos(l), sin(l)}; // Read the physical variables FoMo::tphysvar peakvec=goftcube.readvar(0);//Peak intensity FoMo::tphysvar fwhmvec=goftcube.readvar(1);// line width, =1 for AIA imaging FoMo::tphysvar vx=goftcube.readvar(2); FoMo::tphysvar vy=goftcube.readvar(3); double losvelval; // No openmp possible here // Because of the insertions at the end of the loop, we get segfaults :( /*#ifdef _OPENMP #pragma omp parallel for #endif*/ for (int i=0; i<ng; i++) { for (int j=0; j<2; j++) gridpoint[j]=grid[j][i]; xacc[i]=gridpoint[0]*cos(l)-gridpoint[1]*sin(l);// rotated grid yacc[i]=gridpoint[0]*sin(l)+gridpoint[1]*cos(l); temporarygridpoint=Point(grid[0][i],grid[1][i]); //position vector // also create the map function_values here std::vector<double> velvec = {vx[i], vy[i]};// velocity vector losvelval = inner_product(unit.begin(),unit.end(),velvec.begin(),0.0);//velocity along line of sight for position [i]/[ng] losvelmap[temporarygridpoint]=Coord_type(losvelval); peakmap[temporarygridpoint]=Coord_type(peakvec[i]); fwhmmap[temporarygridpoint]=Coord_type(fwhmvec[i]); /* peakmap.insert(make_pair(temporarygridpoint,Coord_type(peakvec[i]))); fwhmmap.insert(make_pair(temporarygridpoint,Coord_type(fwhmvec[i]))); losvelmap.insert(make_pair(temporarygridpoint,Coord_type(losvelval)));*/ } double minx=*(min_element(xacc.begin(),xacc.end())); double maxx=*(max_element(xacc.begin(),xacc.end())); double miny=*(min_element(yacc.begin(),yacc.end())); double maxy=*(max_element(yacc.begin(),yacc.end())); /* Value_access peak=Value_access(peakmap); Value_access fwhm=Value_access(fwhmmap); Value_access losvel=Value_access(losvelmap);*/ xacc.clear(); // release the memory yacc.clear(); if (commrank==0) std::cout << "Done!" << std::endl; std::string chiantifile=goftcube.readchiantifile(); double lambda0=goftcube.readlambda0();// lambda0=AIA bandpass for AIA imaging double lambda_width_in_A=lambda_width*lambda0/speedoflight; Delaunay_triangulation_2 DT=triangulationfrom2Ddatacube(goftcube); Delaunay_triangulation_2 * DTpointer=&DT; if (commrank==0) std::cout << "Building frame: " << std::flush; double x,y,z,intpolpeak,intpolfwhm,intpollosvel,lambdaval,tempintens; int li,lj,ind; Point p,nearest; Delaunay_triangulation_2::Vertex_handle v; Delaunay_triangulation_2::Locate_type lt; Delaunay_triangulation_2::Face_handle c; boost::progress_display show_progress(x_pixel*y_pixel); //initialize grids FoMo::tgrid newgrid; FoMo::tcoord xvec(x_pixel*lambda_pixel),yvec(x_pixel*lambda_pixel),lambdavec(x_pixel*lambda_pixel); newgrid.push_back(xvec); if (lambda_pixel > 1) newgrid.push_back(lambdavec); FoMo::tphysvar intens(x_pixel*lambda_pixel,0); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) private (x,y,p,lt,li,v,nearest,intpolpeak,intpolfwhm,intpollosvel,lambdaval,tempintens,ind) #endif for (int j=0; j<x_pixel; j++) { #ifdef _OPENMP #pragma omp task #endif for (int i=0; i<y_pixel; i++) // scanning through ccd { x = double(j)/(x_pixel-1)*(maxx-minx)+minx; y = double(i)/(y_pixel-1)*(maxy-miny)+miny; // calculate the interpolation in the original frame of reference // i.e. derotate the point using angles -l and -b p= {x*cos(l)+y*sin(l),-x*sin(l)+y*cos(l)}; c=DTpointer->locate(p,lt,li); // Only look for the nearest point and interpolate, if the point p is inside the convex hull. if (lt!=Delaunay_triangulation_2::OUTSIDE_CONVEX_HULL) { // is this a critical operation? v=DTpointer->nearest_vertex(p,c); nearest=v->point(); /* This is how it is done in the CGAL examples pair<Coord_type,bool> tmppeak=peak(nearest); pair<Coord_type,bool> tmpfwhm=fwhm(nearest); pair<Coord_type,bool> tmplosvel=losvel(nearest); intpolpeak=tmppeak.first; intpolfwhm=tmpfwhm.first; intpollosvel=tmplosvel.first;*/ intpolpeak=peakmap[nearest]; intpolfwhm=fwhmmap[nearest]; intpollosvel=losvelmap[nearest]; } else { intpolpeak=0; } if (lambda_pixel>1)// spectroscopic study { for (int il=0; il<lambda_pixel; il++) // changed index from global variable l into il [D.Y. 17 Nov 2014] { // lambda is made around lambda0, with a width of lambda_width lambdaval=double(il)/(lambda_pixel-1)*lambda_width_in_A-lambda_width_in_A/2.; tempintens=intpolpeak*exp(-pow(lambdaval-intpollosvel/speedoflight*lambda0,2)/pow(intpolfwhm,2)*4.*log(2.)); ind=j*lambda_pixel+il;// newgrid[0][ind]=x; newgrid[2][ind]=lambdaval+lambda0; // this is critical, but with tasks, the ind is unique for each task, and no collision should occur intens[ind]+=tempintens;// loop over z and lambda [D.Y 17 Nov 2014] } } if (lambda_pixel==1) // AIA imaging study. Algorithm not verified [DY 14 Nov 2014] { tempintens=intpolpeak; ind=j; newgrid[0][ind]=x; intens[ind]+=tempintens; // loop over z [D.Y 17 Nov 2014] } // print progress ++show_progress; } } if (commrank==0) std::cout << " Done! " << std::endl << std::flush; FoMo::RenderCube rendercube(goftcube); FoMo::tvars newdata; double pathlength=(maxy-miny)/(y_pixel-1); intens=FoMo::operator*(pathlength*1e8,intens); // assume that the coordinates are given in Mm, and convert to cm newdata.push_back(intens); rendercube.setdata(newgrid,newdata); rendercube.setrendermethod("CGAL2D"); rendercube.setresolution(x_pixel,y_pixel,1,lambda_pixel,lambda_width); if (lambda_pixel == 1) { rendercube.setobservationtype(FoMo::Imaging); } else { rendercube.setobservationtype(FoMo::Spectroscopic); } return rendercube; }
// Matrix and Residual Fills bool HMX_PDE::evaluate( NOX::Epetra::Interface::Required::FillType flag, const Epetra_Vector* soln, Epetra_Vector* tmp_rhs) { // Determine what to fill (F or Jacobian) bool fillF = false; bool fillMatrix = false; if (tmp_rhs != 0) { fillF = true; rhs = tmp_rhs; } else { fillMatrix = true; } // "flag" can be used to determine how accurate your fill of F should be // depending on why we are calling evaluate (Could be using computeF to // populate a Jacobian or Preconditioner). if (flag == NOX::Epetra::Interface::Required::Residual) { // Do nothing for now } else if (flag == NOX::Epetra::Interface::Required::Jac) { // Do nothing for now } else if (flag == NOX::Epetra::Interface::Required::Prec) { // Do nothing for now } else if (flag == NOX::Epetra::Interface::Required::User) { // Do nothing for now } int numDep = depProblems.size(); // Create the overlapped solution and position vectors Epetra_Vector u(*OverlapMap); Epetra_Vector uold(*OverlapMap); std::vector<Epetra_Vector*> dep(numDep); for( int i = 0; i<numDep; i++) dep[i] = new Epetra_Vector(*OverlapMap); Epetra_Vector xvec(*OverlapMap); // Export Solution to Overlap vector // If the vector to be used in the fill is already in the Overlap form, // we simply need to map on-processor from column-space indices to // OverlapMap indices. Note that the old solution is simply fixed data that // needs to be sent to an OverlapMap (ghosted) vector. The conditional // treatment for the current soution vector arises from use of // FD coloring in parallel. uold.Import(*oldSolution, *Importer, Insert); for( int i = 0; i<numDep; i++ ) (*dep[i]).Import(*( (*(depSolutions.find(depProblems[i]))).second ), *Importer, Insert); xvec.Import(*xptr, *Importer, Insert); if( flag == NOX::Epetra::Interface::Required::FD_Res) // Overlap vector for solution received from FD coloring, so simply reorder // on processor u.Export(*soln, *ColumnToOverlapImporter, Insert); else // Communication to Overlap vector is needed u.Import(*soln, *Importer, Insert); // Declare required variables int OverlapNumMyNodes = OverlapMap->NumMyElements(); int OverlapMinMyNodeGID; if (MyPID==0) OverlapMinMyNodeGID = StandardMap->MinMyGID(); else OverlapMinMyNodeGID = StandardMap->MinMyGID()-1; // Setup iterators for looping over each problem source term contribution // to this one's PDE map<string, double>::iterator srcTermIter; map<string, double>::iterator srcTermEnd = SrcTermWeight.end(); // Bundle up the dependent variables in the way needed for computing // the source terms of each reaction /* Epetra_Vector debugSrcTerm(*OverlapMap); map<string, Epetra_Vector*> debugDepVars; debugDepVars.insert( pair<string, Epetra_Vector*>(getName(), &u) ); for( int i = 0; i<numDep; i++ ) debugDepVars.insert( pair<string, Epetra_Vector*> (myManager->getName(depProblems[i]), &dep[i]) ); for( srcTermIter = SrcTermWeight.begin(); srcTermIter != srcTermEnd; srcTermIter++) { HMX_PDE &srcTermProb = dynamic_cast<HMX_PDE&>( myManager->getProblem(srcTermIter->first) ); std::cout << "Inside problem: \"" << getName() << "\" calling to get source term " << "from problem: \"" << srcTermIter->first << "\" :" << std::endl; srcTermProb.computeSourceTerm(debugDepVars, debugSrcTerm); std::cout << "Resulting source term :" << debugSrcTerm << std::endl; } */ int row; double alpha = 500.0; double xx[2]; double uu[2]; double uuold[2]; std::vector<double*> ddep(numDep); for( int i = 0; i<numDep; i++) ddep[i] = new double[2]; double *srcTerm = new double[2]; Basis basis; // Bundle up the dependent variables in the way needed for computing // the source terms of each reaction map<string, double*> depVars; depVars.insert( pair<string, double*>(getName(), uu) ); for( int i = 0; i<numDep; i++ ) depVars.insert( pair<string, double*> (myManager->getProblemName(depProblems[i]), ddep[i]) ); // Do a check on this fill // map<string, double*>::iterator iter; // for( iter = depVars.begin(); iter != depVars.end(); iter++) // std::cout << "Inserted ... " << iter->first << "\t" << iter->second << std::endl; // std::cout << "--------------------------------------------------" << std::endl; // for( iter = depVars.begin(); iter != depVars.end(); iter++) // std::cout << iter->first << "\t" << (iter->second)[0] << ", " // << (iter->second)[1] << std::endl; // std::cout << "--------------------------------------------------" << std::endl; // Zero out the objects that will be filled if ( fillMatrix ) A->PutScalar(0.0); if ( fillF ) rhs->PutScalar(0.0); // Loop Over # of Finite Elements on Processor for (int ne=0; ne < OverlapNumMyNodes-1; ne++) { // Loop Over Gauss Points for(int gp=0; gp < 2; gp++) { // Get the solution and coordinates at the nodes xx[0]=xvec[ne]; xx[1]=xvec[ne+1]; uu[0] = u[ne]; uu[1] = u[ne+1]; uuold[0] = uold[ne]; uuold[1] = uold[ne+1]; for( int i = 0; i<numDep; i++ ) { ddep[i][0] = (*dep[i])[ne]; ddep[i][1] = (*dep[i])[ne+1]; } // Calculate the basis function and variables at the gauss points basis.getBasis(gp, xx, uu, uuold, ddep); // Loop over Nodes in Element for (int i=0; i< 2; i++) { row=OverlapMap->GID(ne+i); if (StandardMap->MyGID(row)) { if ( fillF ) { // First do time derivative and diffusion operator (*rhs)[StandardMap->LID(OverlapMap->GID(ne+i))]+= +basis.wt*basis.dx *((basis.uu - basis.uuold)/dt * basis.phi[i] +(1.0/(basis.dx*basis.dx))*diffCoef*basis.duu*basis.dphide[i]); // Then do source term contributions // for( srcTermIter = SrcTermWeight.begin(); srcTermIter != srcTermEnd; srcTermIter++) { HMX_PDE &srcTermProb = dynamic_cast<HMX_PDE&>( myManager->getProblem((*srcTermIter).first) ); srcTermProb.computeSourceTerm(2, depVars, srcTerm); (*rhs)[StandardMap->LID(OverlapMap->GID(ne+i))]+= +basis.wt*basis.dx *( basis.phi[i] * ( - (*srcTermIter).second * srcTerm[i] )); } // } } // Loop over Trial Functions if ( fillMatrix ) { /* for(j=0;j < 2; j++) { if (StandardMap->MyGID(row)) { column=OverlapMap->GID(ne+j); jac=basis.wt*basis.dx*( basis.phi[j]/dt*basis.phi[i] +(1.0/(basis.dx*basis.dx))*diffCoef*basis.dphide[j]* basis.dphide[i] + basis.phi[i] * ( (beta+1.0)*basis.phi[j] - 2.0*basis.uu*basis.phi[j]*basis.ddep[id_spec]) ); ierr=A->SumIntoGlobalValues(row, 1, &jac, &column); } } */ } } } } // Apply Dirichlet BC for Temperature problem only (for now); this implies // no-flux across domain boundary for all species. if( getName() == tempFieldName ) { // Insert Boundary Conditions and modify Jacobian and function (F) // U(0)=1 if (MyPID==0) { if ( fillF ) (*rhs)[0]= (*soln)[0] - alpha; if ( fillMatrix ) { int column=0; double jac=1.0; A->ReplaceGlobalValues(0, 1, &jac, &column); column=1; jac=0.0; A->ReplaceGlobalValues(0, 1, &jac, &column); } } // U(1)=1 if ( StandardMap->LID(StandardMap->MaxAllGID()) >= 0 ) { int lastDof = StandardMap->LID(StandardMap->MaxAllGID()); if ( fillF ) (*rhs)[lastDof] = (*soln)[lastDof] - alpha; if ( fillMatrix ) { int row=StandardMap->MaxAllGID(); int column = row; double jac = 1.0; A->ReplaceGlobalValues(row, 1, &jac, &column); jac=0.0; column--; A->ReplaceGlobalValues(row, 1, &jac, &column); } } } // Sync up processors to be safe Comm->Barrier(); A->FillComplete(); #ifdef DEBUG A->Print(cout); if( fillF ) std::cout << "For residual fill :" << std::endl << *rhs << std::endl; if( fillMatrix ) { std::cout << "For jacobian fill :" << std::endl; A->Print(cout); } #endif // Cleanup for( int i = 0; i < numDep; ++i) { delete [] ddep[i]; delete dep[i]; } delete [] srcTerm; return true; }
vector<MX> FX::call(const MX &arg){ vector<MX> xvec(1,arg); return call(xvec); }
bool PelletTransport::evaluate(NOX::Epetra::Interface::Required::FillType fType, const Epetra_Vector* soln, Epetra_Vector* tmp_rhs, Epetra_RowMatrix* tmp_matrix) { if( fType == NOX::Epetra::Interface::Required::Jac ) { cout << "This problem only works for Finite-Difference or Matrix-Free Based Jacobians." << " No analytic Jacobian fill available !!" << endl; throw "Problem ERROR"; } else rhs = new Epetra_Vector(*OverlapMap); // Create the overlapped solution and position vectors Epetra_Vector u(*OverlapMap); Epetra_Vector uold(*OverlapMap); Epetra_Vector xvec(*OverlapNodeMap); // Export Solution to Overlap vector uold.Import(*oldSolution, *Importer, Insert); xvec.Import(*xptr, *nodeImporter, Insert); u.Import(*soln, *Importer, Insert); // Declare required variables int i; int OverlapNumMyNodes = OverlapNodeMap->NumMyElements(); MaterialPropBase::PropData materialProps; // Hard-code use of UO2 for now - RWH 5/14/2007 string fixedType = "UO2"; int OverlapMinMyNodeGID; if (MyPID==0) OverlapMinMyNodeGID = StandardNodeMap->MinMyGID(); else OverlapMinMyNodeGID = StandardNodeMap->MinMyGID()-1; int row1, row2; double term1, term2; double flux1, flux2; double xx[2]; double uu[2*NUMSPECIES]; // Use of the anonymous enum is needed for SGI builds double uuold[2*NUMSPECIES]; Basis basis(NumSpecies); // Zero out the objects that will be filled rhs->PutScalar(0.0); ACTIVE_REGIONS propType; // Loop Over # of Finite Elements on Processor for( int ne = 0; ne < OverlapNumMyNodes - 1; ++ne ) { propType = (ACTIVE_REGIONS) (*elemTypes)[ne]; // Loop Over Gauss Points for( int gp = 0; gp < 2; ++gp ) { // Get the solution and coordinates at the nodes xx[0] = xvec[ne]; xx[1] = xvec[ne+1]; for (int k=0; k<NumSpecies; k++) { uu[NumSpecies * 0 + k] = u[NumSpecies * ne + k]; uu[NumSpecies * 1 + k] = u[NumSpecies * (ne+1) + k]; uuold[NumSpecies * 0 + k] = uold[NumSpecies * ne + k]; uuold[NumSpecies * 1 + k] = uold[NumSpecies * (ne+1) + k]; } // Calculate the basis function at the gauss point basis.getBasis(gp, xx, uu, uuold); MaterialPropFactory::computeProps( propType, basis.uu[0], basis.uu[1], materialProps ); double & rho1 = materialProps.density ; double & k1 = materialProps.k_thermal; double & Cp1 = materialProps.Cp ; double & Qstar1 = materialProps.Qstar ; double & Qdot1 = materialProps.Qdot ; double & Ffunc = materialProps.thermoF ; double & D_diff1 = materialProps.D_diff ; // Loop over Nodes in Element for( i = 0; i < 2; ++i ) { row1=OverlapMap->GID(NumSpecies * (ne+i)); row2=OverlapMap->GID(NumSpecies * (ne+i) + 1); flux1 = -k1*basis.duu[0]/basis.dx; flux2 = -0.5*D_diff1*(basis.duu[1]/basis.dx + basis.uu[1]*Qstar1/(Ffunc*8.3142*basis.uu[0]*basis.uu[0])*basis.duu[0]/basis.dx); term1 = basis.wt*basis.dx*basis.xx*( rho1*Cp1*(basis.uu[0] - basis.uuold[0])/dt * basis.phi[i] - flux1*basis.dphide[i]/basis.dx - Qdot1*basis.phi[i] ); term2 = basis.wt*basis.dx*basis.xx*( 0.5*(basis.uu[1] - basis.uuold[1])/dt * basis.phi[i] - flux2*basis.dphide[i]/basis.dx ); (*rhs)[NumSpecies*(ne+i)] += term1; (*rhs)[NumSpecies*(ne+i)+1] += term2; } } } // Insert Boundary Conditions and modify Jacobian and function (F) // Dirichlet BCs at xminUO2 const double xB = dynamic_cast<const MaterialProp_UO2 &>(MaterialPropFactory::factory().get_model(PelletTransport::UO2)).get_xB(); if (MyPID==0) { // Use no-flux BCs //(*rhs)[0]= (*soln)[0] - 0.6; //(*rhs)[1]= (*soln)[1] - 10.0/3.0; } // Dirichlet BCs at xmaxUO2 if( StandardMap->LID(NumSpecies*(NumGlobalElementsUO2)) >= 0 ) { int lastUO2Dof = StandardMap->LID(NumSpecies*(NumGlobalElementsUO2) + 1); //(*rhs)[lastDof - 1] = (*soln)[lastDof - 1] - 840.0; (*rhs)[lastUO2Dof] = (*soln)[lastUO2Dof] - xB; } // Dirichlet BCs at all He and Clad species variables int lastUO2DofGID = NumSpecies*NumGlobalElementsUO2 + 1; int lastGID = StandardMap->MaxAllGID(); for( int i = lastUO2DofGID; i < lastGID; i+=2 ) if( StandardMap->LID(i) >= 0 ) (*rhs)[StandardMap->LID(i)] = (*soln)[StandardMap->LID(i)] - xB; // Dirichlet BCs at xmaxClad if( StandardMap->LID(StandardMap->MaxAllGID()) >= 0 ) { int lastDof = StandardMap->LID(StandardMap->MaxAllGID()); (*rhs)[lastDof - 1] = (*soln)[lastDof - 1] - 750.0; (*rhs)[lastDof] = (*soln)[lastDof] - xB; } // Sync up processors to be safe Comm->Barrier(); // Do an assemble for overlap nodes tmp_rhs->Export(*rhs, *Importer, Add); delete rhs; return true; }
// Matrix and Residual Fills bool Brusselator::evaluate(NOX::Epetra::Interface::Required::FillType fType, const Epetra_Vector* soln, Epetra_Vector* tmp_rhs, Epetra_RowMatrix* tmp_matrix, double jac_coeff, double mass_coeff) { if( fType == NOX::Epetra::Interface::Required::Jac ) { if( overlapType == NODES ) { cout << "This problem only works for Finite-Difference Based Jacobians" << endl << "when overlapping nodes." << endl << "No analytic Jacobian fill available !!" << endl; exit(1); } flag = MATRIX_ONLY; } else { flag = F_ONLY; if( overlapType == NODES ) rhs = new Epetra_Vector(*OverlapMap); else rhs = tmp_rhs; } // cout << "\nfTpye--> " << fType << endl // << "Incoming soln vector :\n" << endl << *soln << endl; // Create the overlapped solution and position vectors Epetra_Vector u(*OverlapMap); Epetra_Vector udot(*OverlapMap); Epetra_Vector xvec(*OverlapNodeMap); // Export Solution to Overlap vector // If the vector to be used in the fill is already in the Overlap form, // we simply need to map on-processor from column-space indices to // OverlapMap indices. Note that the old solution is simply fixed data that // needs to be sent to an OverlapMap (ghosted) vector. The conditional // treatment for the current soution vector arises from use of // FD coloring in parallel. udot.Import(*solnDot, *Importer, Insert); xvec.Import(*xptr, *nodeImporter, Insert); if( (overlapType == ELEMENTS) && (fType == NOX::Epetra::Interface::Required::FD_Res) ) // Overlap vector for solution received from FD coloring, so simply reorder // on processor u.Export(*soln, *ColumnToOverlapImporter, Insert); else // Communication to Overlap vector is needed u.Import(*soln, *Importer, Insert); // Declare required variables int i,j,ierr; int OverlapNumMyNodes = OverlapNodeMap->NumMyElements(); //int OverlapNumMyUnknowns = OverlapMap->NumMyElements(); int OverlapMinMyNodeGID; if (MyPID==0) OverlapMinMyNodeGID = StandardNodeMap->MinMyGID(); else OverlapMinMyNodeGID = StandardNodeMap->MinMyGID()-1; int row1, row2, column1, column2; double term1, term2; double Dcoeff1 = 0.025; double Dcoeff2 = 0.025; // double alpha = 0.6; // double beta = 2.0; double jac11, jac12, jac21, jac22; double xx[2]; double uu[2*NUMSPECIES]; // Use of the anonymous enum is needed for SGI builds double uudot[2*NUMSPECIES]; Basis basis(NumSpecies); // Zero out the objects that will be filled if ((flag == MATRIX_ONLY) || (flag == ALL)) A->PutScalar(0.0); if ((flag == F_ONLY) || (flag == ALL)) rhs->PutScalar(0.0); // Loop Over # of Finite Elements on Processor for (int ne=0; ne < OverlapNumMyNodes - 1; ne++) { // Loop Over Gauss Points for(int gp=0; gp < 2; gp++) { // Get the solution and coordinates at the nodes xx[0]=xvec[ne]; xx[1]=xvec[ne+1]; for (int k=0; k<NumSpecies; k++) { uu[NumSpecies * 0 + k] = u[NumSpecies * ne + k]; uu[NumSpecies * 1 + k] = u[NumSpecies * (ne+1) + k]; uudot[NumSpecies * 0 + k] = udot[NumSpecies * ne + k]; uudot[NumSpecies * 1 + k] = udot[NumSpecies * (ne+1) + k]; } // Calculate the basis function at the gauss point basis.getBasis(gp, xx, uu, uudot); // Loop over Nodes in Element for (i=0; i< 2; i++) { row1=OverlapMap->GID(NumSpecies * (ne+i)); row2=OverlapMap->GID(NumSpecies * (ne+i) + 1); term1 = basis.wt*basis.dx * ( basis.uudot[0] * basis.phi[i] +(1.0/(basis.dx*basis.dx))*Dcoeff1*basis.duu[0]*basis.dphide[i] + basis.phi[i] * ( -alpha + (beta+1.0)*basis.uu[0] - basis.uu[0]*basis.uu[0]*basis.uu[1]) ); term2 = basis.wt*basis.dx * ( basis.uudot[1] * basis.phi[i] +(1.0/(basis.dx*basis.dx))*Dcoeff2*basis.duu[1]*basis.dphide[i] + basis.phi[i] * ( -beta*basis.uu[0] + basis.uu[0]*basis.uu[0]*basis.uu[1]) ); //printf("Proc=%d GlobalRow=%d LocalRow=%d Owned=%d\n", // MyPID, row, ne+i,StandardMap.MyGID(row)); if ((flag == F_ONLY) || (flag == ALL)) { if( overlapType == NODES ) { (*rhs)[NumSpecies*(ne+i)] += term1; (*rhs)[NumSpecies*(ne+i)+1] += term2; } else if (StandardMap->MyGID(row1)) { (*rhs)[StandardMap->LID(OverlapMap->GID(NumSpecies*(ne+i)))]+= term1; (*rhs)[StandardMap->LID(OverlapMap->GID(NumSpecies*(ne+i)+1))]+= term2; } } // Loop over Trial Functions if ((flag == MATRIX_ONLY) || (flag == ALL)) { for(j=0;j < 2; j++) { if (StandardMap->MyGID(row1)) { column1=OverlapMap->GID(NumSpecies * (ne+j)); column2=OverlapMap->GID(NumSpecies * (ne+j) + 1); jac11=basis.wt*basis.dx*( mass_coeff*basis.phi[j]*basis.phi[i] +jac_coeff* +((1.0/(basis.dx*basis.dx))*Dcoeff1*basis.dphide[j]* basis.dphide[i] + basis.phi[i] * ( (beta+1.0)*basis.phi[j] - 2.0*basis.uu[0]*basis.phi[j]*basis.uu[1])) ); jac12=basis.wt*basis.dx*( jac_coeff*basis.phi[i] * ( -basis.uu[0]*basis.uu[0]*basis.phi[j]) ); jac21=basis.wt*basis.dx*( jac_coeff*basis.phi[i] * ( -beta*basis.phi[j] + 2.0*basis.uu[0]*basis.phi[j]*basis.uu[1]) ); jac22=basis.wt*basis.dx*( mass_coeff*basis.phi[j]*basis.phi[i] +jac_coeff* +((1.0/(basis.dx*basis.dx))*Dcoeff2*basis.dphide[j]* basis.dphide[i] + basis.phi[i] * basis.uu[0]*basis.uu[0]*basis.phi[j] )); ierr=A->SumIntoGlobalValues(row1, 1, &jac11, &column1); column1++; ierr=A->SumIntoGlobalValues(row1, 1, &jac12, &column1); ierr=A->SumIntoGlobalValues(row2, 1, &jac22, &column2); column2--; ierr=A->SumIntoGlobalValues(row2, 1, &jac21, &column2); } } } } } } // Insert Boundary Conditions and modify Jacobian and function (F) // U(0)=1 if (MyPID==0) { if ((flag == F_ONLY) || (flag == ALL)) { (*rhs)[0]= (*soln)[0] - alpha; (*rhs)[1]= (*soln)[1] - beta/alpha; } if ((flag == MATRIX_ONLY) || (flag == ALL)) { int column=0; double jac=1.0*jac_coeff; A->ReplaceGlobalValues(0, 1, &jac, &column); column++; A->ReplaceGlobalValues(1, 1, &jac, &column); jac=0.0; column=0; A->ReplaceGlobalValues(1, 1, &jac, &column); column++; A->ReplaceGlobalValues(0, 1, &jac, &column); column++; A->ReplaceGlobalValues(0, 1, &jac, &column); A->ReplaceGlobalValues(1, 1, &jac, &column); column++; A->ReplaceGlobalValues(0, 1, &jac, &column); A->ReplaceGlobalValues(1, 1, &jac, &column); } } // U(1)=1 if ( StandardMap->LID(StandardMap->MaxAllGID()) >= 0 ) { int lastDof = StandardMap->LID(StandardMap->MaxAllGID()); if ((flag == F_ONLY) || (flag == ALL)) { (*rhs)[lastDof - 1] = (*soln)[lastDof - 1] - alpha; (*rhs)[lastDof] = (*soln)[lastDof] - beta/alpha; } if ((flag == MATRIX_ONLY) || (flag == ALL)) { int row=StandardMap->MaxAllGID() - 1; int column = row; double jac = 1.0*jac_coeff; A->ReplaceGlobalValues(row++, 1, &jac, &column); column++; A->ReplaceGlobalValues(row, 1, &jac, &column); jac=0.0; row = column - 1; A->ReplaceGlobalValues(row, 1, &jac, &column); column--; A->ReplaceGlobalValues(row+1, 1, &jac, &column); column--; A->ReplaceGlobalValues(row, 1, &jac, &column); A->ReplaceGlobalValues(row+1, 1, &jac, &column); column--; A->ReplaceGlobalValues(row, 1, &jac, &column); A->ReplaceGlobalValues(row+1, 1, &jac, &column); } } // Sync up processors to be safe Comm->Barrier(); // Do an assemble for overlap nodes if( overlapType == NODES ) tmp_rhs->Export(*rhs, *Importer, Add); // Comm->Barrier(); // cout << "Returned tmp_rhs residual vector :\n" << endl << *tmp_rhs << endl; return true; }
void MeshTopoData::ApplyMap(int mapType, BOOL normalizeMap, Matrix3 gizmoTM, UnwrapMod *mod) { //this just catches some strane cases where the z axis is 0 which causes some bad numbers /* if (Length(gizmoTM.GetRow(2)) == 0.0f) { gizmoTM.SetRow(2,Point3(0.0f,0.0f,1.0f)); } */ float circ = 1.0f; /* if (!normalizeMap) { for (int i = 0; i < 3; i++) { Point3 vec = gizmoTM.GetRow(i); vec = Normalize(vec); gizmoTM.SetRow(i,vec); } } */ Matrix3 toGizmoSpace = gizmoTM; BitArray tempVSel; DetachFromGeoFaces(mFSel, tempVSel, mod); TimeValue t = GetCOREInterface()->GetTime(); //build available list if (mapType == SPHERICALMAP) { Tab<int> quads; quads.SetCount(TVMaps.v.Count()); float longestR = 0.0f; for (int i = 0; i < TVMaps.v.Count(); i++) { BOOL found = FALSE; quads[i] = -1; if (tempVSel[i]) { Point3 tp = TVMaps.v[i].GetP() * gizmoTM;//gverts.d[i].p * gtm; //z our y int quad = 0; if ((tp.x >= 0) && (tp.y >= 0)) quad = 0; else if ((tp.x < 0) && (tp.y >= 0)) quad = 1; else if ((tp.x < 0) && (tp.y < 0)) quad = 2; else if ((tp.x >= 0) && (tp.y < 0)) quad = 3; quads[i] = quad; //find the quad the point is in Point3 xvec(1.0f,0.0f,0.0f); Point3 zvec(0.0f,0.0f,-1.0f); float x= 0.0f; Point3 zp = tp; zp.z = 0.0f; float dot = DotProd(xvec,Normalize(zp)); float angle = 0.0f; if (dot >= 1.0f) angle = 0.0f; else angle = acos(dot); x = angle/(PI*2.0f); if (quad > 1) x = (0.5f - x) + 0.5f; dot = DotProd(zvec,Normalize(tp)); float yangle = 0.0f; if (dot >= 1.0f) yangle = 0.0f; else yangle = acos(dot); float y = yangle/(PI); tp.x = x; tp.y = y;//tp.z; float d = Length(tp); tp.z = d; if (d > longestR) longestR = d; TVMaps.v[i].SetFlag( 0 ); TVMaps.v[i].SetInfluence( 0.0f ); TVMaps.v[i].SetP(tp); TVMaps.v[i].SetControlID(-1); mVSel.Set(i); /* if (ct < alist.Count() ) { int j = alist[ct]; TVMaps.v[j].flags = 0; TVMaps.v[j].influence = 0.0f; TVMaps.v[j].p = tp; vsel.Set(j); if (TVMaps.cont[j]) TVMaps.cont[j]->SetValue(0,&tp,CTRL_ABSOLUTE); gverts.d[i].newindex = j; ct++; } else { UVW_TVVertClass tempv; tempv.p = tp; tempv.flags = 0; tempv.influence = 0.0f; gverts.d[i].newindex = TVMaps.v.Count(); TVMaps.v.Append(1,&tempv,5000); int vct = TVMaps.v.Count()-1; extraSel.Append(1,&vct,5000); Control* c; c = NULL; TVMaps.cont.Append(1,&c,5000); if (TVMaps.cont[TVMaps.v.Count()-1]) TVMaps.cont[TVMaps.v.Count()-1]->SetValue(0,&TVMaps.v[TVMaps.v.Count()-1].p,CTRL_ABSOLUTE); } */ } } //now copy our face data over Tab<int> faceAcrossSeam; for (int i = 0; i < TVMaps.f.Count(); i++) { if (mFSel[i]) { // ActiveAddFaces.Append(1,&i,1); int ct = i;//gfaces[i]->FaceIndex; // TVMaps.f[ct]->flags = gfaces[i]->flags; // TVMaps.f[ct]->flags |= FLAG_SELECTED; int pcount = 3; // if (gfaces[i].flags & FLAG_QUAD) pcount = 4; pcount = TVMaps.f[i]->count;//gfaces[i]->count; int quad0 = 0; int quad3 = 0; for (int j = 0; j < pcount; j++) { int index = TVMaps.f[i]->t[j]; if (quads[index] == 0) quad0++; if (quads[index] == 3) quad3++; //find spot in our list // TVMaps.f[ct]->t[j] = gverts.d[index].newindex; if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs)) { index = TVMaps.f[i]->vecs->handles[j*2]; if (quads[index] == 0) quad0++; if (quads[index] == 3) quad3++; //find spot in our list // TVMaps.f[ct]->vecs->handles[j*2] = gverts.d[index].newindex; index = TVMaps.f[i]->vecs->handles[j*2+1]; if (quads[index] == 0) quad0++; if (quads[index] == 3) quad3++; //find spot in our list // TVMaps.f[ct]->vecs->handles[j*2+1] = gverts.d[index].newindex; if (TVMaps.f[ct]->flags & FLAG_INTERIOR) { index = TVMaps.f[i]->vecs->interiors[j]; if (quads[index] == 0) quad0++; if (quads[index] == 3) quad3++; //find spot in our list // TVMaps.f[ct]->vecs->interiors[j] = gverts.d[index].newindex; } } } if ((quad3 > 0) && (quad0 > 0)) { for (int j = 0; j < pcount; j++) { //find spot in our list int index = TVMaps.f[ct]->t[j]; if (TVMaps.v[index].GetP().x <= 0.25f) { UVW_TVVertClass tempv = TVMaps.v[index]; Point3 fp = tempv.GetP(); fp.x += 1.0f; tempv.SetP(fp); tempv.SetFlag(0); tempv.SetInfluence( 0.0f); TVMaps.v.Append(1,&tempv,5000); int vct = TVMaps.v.Count()-1; TVMaps.f[ct]->t[j] = vct; } if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs)) { //find spot in our list int index = TVMaps.f[ct]->vecs->handles[j*2]; if (TVMaps.v[index].GetP().x <= 0.25f) { UVW_TVVertClass tempv = TVMaps.v[index]; Point3 fp = tempv.GetP(); fp.x += 1.0f; tempv.SetP(fp); tempv.SetFlag(0); tempv.SetInfluence( 0.0f); TVMaps.v.Append(1,&tempv,5000); int vct = TVMaps.v.Count()-1; TVMaps.f[ct]->vecs->handles[j*2] = vct; } //find spot in our list index = TVMaps.f[ct]->vecs->handles[j*2+1]; if (TVMaps.v[index].GetP().x <= 0.25f) { UVW_TVVertClass tempv = TVMaps.v[index]; Point3 fp = tempv.GetP(); fp.x += 1.0f; tempv.SetP(fp); tempv.SetFlag(0); tempv.SetInfluence( 0.0f); TVMaps.v.Append(1,&tempv,5000); int vct = TVMaps.v.Count()-1; TVMaps.f[ct]->vecs->handles[j*2+1] = vct; } if (TVMaps.f[ct]->flags & FLAG_INTERIOR) { index = TVMaps.f[ct]->vecs->interiors[j]; if (TVMaps.v[index].GetP().x <= 0.25f) { UVW_TVVertClass tempv = TVMaps.v[index]; Point3 fp = tempv.GetP(); fp.x += 1.0f; tempv.SetP(fp); tempv.SetFlag(0); tempv.SetInfluence( 0.0f); TVMaps.v.Append(1,&tempv,5000); int vct = TVMaps.v.Count()-1; TVMaps.f[ct]->vecs->interiors[j] = vct; } } } } } } } if (!normalizeMap) { BitArray processedVerts; processedVerts.SetSize(TVMaps.v.Count()); processedVerts.ClearAll(); circ = circ * PI * longestR * 2.0f; for (int i = 0; i < TVMaps.f.Count(); i++) { if (mFSel[i]) { int pcount = 3; // if (gfaces[i].flags & FLAG_QUAD) pcount = 4; pcount = TVMaps.f[i]->count; int ct = i; for (int j = 0; j < pcount; j++) { //find spot in our list int index = TVMaps.f[ct]->t[j]; if (!processedVerts[index]) { Point3 p = TVMaps.v[index].GetP(); p.x *= circ; p.y *= circ; TVMaps.v[index].SetP(p); processedVerts.Set(index,TRUE); } if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs)) { //find spot in our list int index = TVMaps.f[ct]->vecs->handles[j*2]; if (!processedVerts[index]) { Point3 p = TVMaps.v[index].GetP(); p.x *= circ; p.y *= circ; TVMaps.v[index].SetP(p); processedVerts.Set(index,TRUE); } //find spot in our list index = TVMaps.f[ct]->vecs->handles[j*2+1]; if (!processedVerts[index]) { Point3 p = TVMaps.v[index].GetP(); p.x *= circ; p.y *= circ; TVMaps.v[index].SetP(p); processedVerts.Set(index,TRUE); } if (TVMaps.f[ct]->flags & FLAG_INTERIOR) { index = TVMaps.f[ct]->vecs->interiors[j]; if (!processedVerts[index]) { Point3 p = TVMaps.v[index].GetP(); p.x *= circ; p.y *= circ; TVMaps.v[index].SetP(p); processedVerts.Set(index,TRUE); } } } } } } } //now find the seam mVSel.SetSize(TVMaps.v.Count(), 1); mVSel.Set(TVMaps.v.Count()-1); TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count(), 1); /* for (int i = 0; i < extraSel.Count(); i++) vsel.Set(extraSel[i],TRUE); */ } else if (mapType == CYLINDRICALMAP) { Tab<int> quads; quads.SetCount(TVMaps.v.Count()); float longestR = 0.0f; for (int i = 0; i < TVMaps.v.Count(); i++) { BOOL found = FALSE; quads[i] = -1; if (tempVSel[i]) // if (gverts.sel[i]) { Point3 gp = TVMaps.v[i].GetP();//gverts.d[i].p; Point3 tp = gp * toGizmoSpace; //z our y int quad = 0; if ((tp.x >= 0) && (tp.y >= 0)) quad = 0; else if ((tp.x < 0) && (tp.y >= 0)) quad = 1; else if ((tp.x < 0) && (tp.y < 0)) quad = 2; else if ((tp.x >= 0) && (tp.y < 0)) quad = 3; quads[i] = quad; //find the quad the point is in Point3 xvec(1.0f,0.0f,0.0f); float x= 0.0f; Point3 zp = tp; zp.z = 0.0f; float dot = DotProd(xvec,Normalize(zp)); float angle = 0.0f; if (dot >= 1.0f) angle = 0.0f; else angle = acos(dot); x = angle/(PI*2.0f); if (quad > 1) x = (0.5f - x) + 0.5f; TVMaps.v[i].SetFlag(0); TVMaps.v[i].SetInfluence(0.0f); Point3 fp; fp.x = x; fp.y = tp.z; float d = Length(zp); fp.z = d; SetTVVert(t,i,fp,mod); if (d > longestR) longestR = d; } } //now copy our face data over Tab<int> faceAcrossSeam; for (int i = 0; i < TVMaps.f.Count(); i++) { if (mFSel[i]) { int ct = i; int pcount = 3; // if (gfaces[i].flags & FLAG_QUAD) pcount = 4; pcount = TVMaps.f[i]->count; int quad0 = 0; int quad3 = 0; for (int j = 0; j < pcount; j++) { int index = TVMaps.f[i]->t[j]; if (quads[index] == 0) quad0++; if (quads[index] == 3) quad3++; if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs)) { index = TVMaps.f[i]->vecs->handles[j*2]; if (quads[index] == 0) quad0++; if (quads[index] == 3) quad3++; index = TVMaps.f[i]->vecs->handles[j*2+1]; if (quads[index] == 0) quad0++; if (quads[index] == 3) quad3++; //find spot in our list if (TVMaps.f[ct]->flags & FLAG_INTERIOR) { index = TVMaps.f[i]->vecs->interiors[j]; if (quads[index] == 0) quad0++; if (quads[index] == 3) quad3++; } } } if ((quad3 > 0) && (quad0 > 0)) { for (int j = 0; j < pcount; j++) { //find spot in our list int index = TVMaps.f[ct]->t[j]; if (TVMaps.v[index].GetP().x <= 0.25f) { UVW_TVVertClass tempv = TVMaps.v[index]; Point3 tpv = tempv.GetP(); tpv.x += 1.0f; tempv.SetP(tpv); tempv.SetFlag(0); tempv.SetInfluence(0.0f); tempv.SetControlID(-1); TVMaps.v.Append(1,&tempv,5000); int vct = TVMaps.v.Count()-1; TVMaps.f[ct]->t[j] = vct; } if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs)) { //find spot in our list int index = TVMaps.f[ct]->vecs->handles[j*2]; if (TVMaps.v[index].GetP().x <= 0.25f) { UVW_TVVertClass tempv = TVMaps.v[index]; Point3 tpv = tempv.GetP(); tpv.x += 1.0f; tempv.SetP(tpv); tempv.SetFlag(0); tempv.SetInfluence(0.0f); tempv.SetControlID(-1); TVMaps.v.Append(1,&tempv,5000); int vct = TVMaps.v.Count()-1; TVMaps.f[ct]->vecs->handles[j*2] = vct; } //find spot in our list index = TVMaps.f[ct]->vecs->handles[j*2+1]; if (TVMaps.v[index].GetP().x <= 0.25f) { UVW_TVVertClass tempv = TVMaps.v[index]; Point3 tpv = tempv.GetP(); tpv.x += 1.0f; tempv.SetP(tpv); tempv.SetFlag(0); tempv.SetInfluence(0.0f); tempv.SetControlID(-1); TVMaps.v.Append(1,&tempv,5000); int vct = TVMaps.v.Count()-1; TVMaps.f[ct]->vecs->handles[j*2+1] = vct; } if (TVMaps.f[ct]->flags & FLAG_INTERIOR) { index = TVMaps.f[ct]->vecs->interiors[j]; if (TVMaps.v[index].GetP().x <= 0.25f) { UVW_TVVertClass tempv = TVMaps.v[index]; Point3 tpv = tempv.GetP(); tpv.x += 1.0f; tempv.SetP(tpv); tempv.SetFlag(0); tempv.SetInfluence(0.0f); tempv.SetControlID(-1); TVMaps.v.Append(1,&tempv,5000); int vct = TVMaps.v.Count()-1; TVMaps.f[ct]->vecs->interiors[j] = vct; } } } } } } } if (!normalizeMap) { BitArray processedVerts; processedVerts.SetSize(GetNumberTVVerts());//TVMaps.v.Count()); processedVerts.ClearAll(); circ = circ * PI * longestR * 2.0f; for (int i = 0; i < GetNumberFaces(); i++)//gfaces.Count(); i++) { if (mFSel[i]) { int pcount = 3; // if (gfaces[i].flags & FLAG_QUAD) pcount = 4; pcount = GetFaceDegree(i);//gfaces[i]->count; int ct = i;//gfaces[i]->FaceIndex; for (int j = 0; j < pcount; j++) { //find spot in our list int index = TVMaps.f[ct]->t[j]; if (!processedVerts[index]) { Point3 p = TVMaps.v[index].GetP(); p.x *= circ; TVMaps.v[index].SetP(p); processedVerts.Set(index,TRUE); } if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs)) { //find spot in our list int index = TVMaps.f[ct]->vecs->handles[j*2]; if (!processedVerts[index]) { Point3 p = TVMaps.v[index].GetP(); p.x *= circ; TVMaps.v[index].SetP(p); processedVerts.Set(index,TRUE); } //find spot in our list index = TVMaps.f[ct]->vecs->handles[j*2+1]; if (!processedVerts[index]) { Point3 p = TVMaps.v[index].GetP(); p.x *= circ; TVMaps.v[index].SetP(p); processedVerts.Set(index,TRUE); } if (TVMaps.f[ct]->flags & FLAG_INTERIOR) { index = TVMaps.f[ct]->vecs->interiors[j]; if (!processedVerts[index]) { Point3 p = TVMaps.v[index].GetP(); p.x *= circ; TVMaps.v[index].SetP(p); processedVerts.Set(index,TRUE); } } } } } } } //now find the seam mVSel.SetSize(TVMaps.v.Count(), 1); mVSel.Set(TVMaps.v.Count()-1); TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count(), 1); // for (int i = 0; i < extraSel.Count(); i++) // vsel.Set(extraSel[i],TRUE); } else if ((mapType == PLANARMAP) || (mapType == PELTMAP)|| (mapType == BOXMAP)) { for (int i = 0; i < TVMaps.v.Count(); i++) { if (tempVSel[i]) { TVMaps.v[i].SetFlag(0); TVMaps.v[i].SetInfluence(0.0f); Point3 tp = TVMaps.v[i].GetP(); tp = tp * toGizmoSpace; tp.x += 0.5f; tp.y += 0.5f; tp.z = 0.0f; SetTVVert(t,i,tp,mod); } } } BuildTVEdges(); BuildVertexClusterList(); }
// Matrix and Residual Fills bool Brusselator::evaluate(FillType fType, const Epetra_Vector* soln, Epetra_Vector* tmp_rhs, Epetra_RowMatrix* tmp_matrix, double jac_coeff, double mass_coeff) { // Set the incoming linear objects if (fType == F_ONLY) { rhs = tmp_rhs; } else if (fType == MATRIX_ONLY) { A = dynamic_cast<Epetra_CrsMatrix*> (tmp_matrix); } else if (fType == ALL) { rhs = tmp_rhs; A = dynamic_cast<Epetra_CrsMatrix*> (tmp_matrix); } else { cout << "Brusselator::evaluate() - FillType fType is broken" << endl; throw; } // Create the overlapped solution and position vectors Epetra_Vector u(*OverlapMap); Epetra_Vector xvec(*OverlapNodeMap); // Export Solution to Overlap vector xvec.Import(*xptr, *nodeImporter, Insert); u.Import(*soln, *Importer, Insert); // Declare required variables int i,j,ierr; int OverlapNumMyNodes = OverlapNodeMap->NumMyElements(); //int OverlapNumMyUnknowns = OverlapMap->NumMyElements(); int OverlapMinMyNodeGID; if (MyPID==0) OverlapMinMyNodeGID = StandardNodeMap->MinMyGID(); else OverlapMinMyNodeGID = StandardNodeMap->MinMyGID()-1; int row1, row2, column1, column2; double term1, term2; double jac11, jac12, jac21, jac22; double xx[2]; double uu[2*NUMSPECIES]; // Use of the anonymous enum is needed for SGI builds Basis basis(NumSpecies); // Zero out the objects that will be filled if ((fType == MATRIX_ONLY) || (fType == ALL)) A->PutScalar(0.0); if ((fType == F_ONLY) || (fType == ALL)) rhs->PutScalar(0.0); // Loop Over # of Finite Elements on Processor for (int ne=0; ne < OverlapNumMyNodes - 1; ne++) { // Loop Over Gauss Points for(int gp=0; gp < 2; gp++) { // Get the solution and coordinates at the nodes xx[0]=xvec[ne]; xx[1]=xvec[ne+1]; for (int k=0; k<NumSpecies; k++) { uu[NumSpecies * 0 + k] = u[NumSpecies * ne + k]; uu[NumSpecies * 1 + k] = u[NumSpecies * (ne+1) + k]; } // Calculate the basis function at the gauss point basis.getBasis(gp, xx, uu); // Loop over Nodes in Element for (i=0; i< 2; i++) { row1=OverlapMap->GID(NumSpecies * (ne+i)); row2=OverlapMap->GID(NumSpecies * (ne+i) + 1); term1 = basis.wt*basis.dx *((1.0/(basis.dx*basis.dx))*D1*basis.duu[0]*basis.dphide[i] + basis.phi[i] * ( -alpha + (beta+1.0)*basis.uu[0] - basis.uu[0]*basis.uu[0]*basis.uu[1]) ); term2 = basis.wt*basis.dx *((1.0/(basis.dx*basis.dx))*D2*basis.duu[1]*basis.dphide[i] + basis.phi[i] * ( -beta*basis.uu[0] + basis.uu[0]*basis.uu[0]*basis.uu[1]) ); //printf("Proc=%d GlobalRow=%d LocalRow=%d Owned=%d\n", // MyPID, row, ne+i,StandardMap.MyGID(row)); if ((fType == F_ONLY) || (fType == ALL)) { if (StandardMap->MyGID(row1)) { (*rhs)[StandardMap->LID(OverlapMap->GID(NumSpecies*(ne+i)))]+= term1; (*rhs)[StandardMap->LID(OverlapMap->GID(NumSpecies*(ne+i)+1))]+= term2; } } // Loop over Trial Functions if ((fType == MATRIX_ONLY) || (fType == ALL)) { for(j=0;j < 2; j++) { if (StandardMap->MyGID(row1)) { column1=OverlapMap->GID(NumSpecies * (ne+j)); column2=OverlapMap->GID(NumSpecies * (ne+j) + 1); jac11=basis.wt*basis.dx *(-mass_coeff*basis.phi[j]*basis.phi[i] +jac_coeff* ((1.0/(basis.dx*basis.dx))*D1*basis.dphide[j]* basis.dphide[i] + basis.phi[i]*((beta+1.0)*basis.phi[j] -2.0*basis.uu[0]*basis.phi[j]*basis.uu[1]))); jac12=basis.wt*basis.dx *(jac_coeff*basis.phi[i] *(-basis.uu[0]*basis.uu[0]*basis.phi[j])); jac21=basis.wt*basis.dx *(jac_coeff*basis.phi[i] *(-beta*basis.phi[j] + 2.0*basis.uu[0]*basis.phi[j]*basis.uu[1]) ); jac22=basis.wt*basis.dx *(-mass_coeff*basis.phi[j]*basis.phi[i] +jac_coeff* ((1.0/(basis.dx*basis.dx))*D2*basis.dphide[j]* basis.dphide[i] + basis.phi[i] * basis.uu[0]*basis.uu[0]*basis.phi[j] )); ierr=A->SumIntoGlobalValues(row1, 1, &jac11, &column1); column1++; ierr=A->SumIntoGlobalValues(row1, 1, &jac12, &column1); ierr=A->SumIntoGlobalValues(row2, 1, &jac22, &column2); column2--; ierr=A->SumIntoGlobalValues(row2, 1, &jac21, &column2); } } } } } } // Insert Boundary Conditions and modify Jacobian and function (F) // T(0)=alpha, C(0) = beta/alpha if (MyPID==0) { if ((fType == F_ONLY) || (fType == ALL)) { (*rhs)[0]= (*soln)[0] - alpha; (*rhs)[1]= (*soln)[1] - beta/alpha; } if ((fType == MATRIX_ONLY) || (fType == ALL)) { int column=0; double jac=1.0*jac_coeff; A->ReplaceGlobalValues(0, 1, &jac, &column); column++; A->ReplaceGlobalValues(1, 1, &jac, &column); jac=0.0; column=0; A->ReplaceGlobalValues(1, 1, &jac, &column); column++; A->ReplaceGlobalValues(0, 1, &jac, &column); column++; A->ReplaceGlobalValues(0, 1, &jac, &column); A->ReplaceGlobalValues(1, 1, &jac, &column); column++; A->ReplaceGlobalValues(0, 1, &jac, &column); A->ReplaceGlobalValues(1, 1, &jac, &column); } } // T(1)=alpha, C(1) = beta/alpha if ( StandardMap->LID(StandardMap->MaxAllGID()) >= 0 ) { int lastDof = StandardMap->LID(StandardMap->MaxAllGID()); if ((fType == F_ONLY) || (fType == ALL)) { (*rhs)[lastDof - 1] = (*soln)[lastDof - 1] - alpha; (*rhs)[lastDof] = (*soln)[lastDof] - beta/alpha; } if ((fType == MATRIX_ONLY) || (fType == ALL)) { int row=StandardMap->MaxAllGID() - 1; int column = row; double jac = 1.0*jac_coeff; A->ReplaceGlobalValues(row++, 1, &jac, &column); column++; A->ReplaceGlobalValues(row, 1, &jac, &column); jac=0.0; row = column - 1; A->ReplaceGlobalValues(row, 1, &jac, &column); column--; A->ReplaceGlobalValues(row+1, 1, &jac, &column); column--; A->ReplaceGlobalValues(row, 1, &jac, &column); A->ReplaceGlobalValues(row+1, 1, &jac, &column); column--; A->ReplaceGlobalValues(row, 1, &jac, &column); A->ReplaceGlobalValues(row+1, 1, &jac, &column); } } // Sync up processors to be safe Comm->Barrier(); A->FillComplete(); return true; }