/** * Returns a V3D object from the Python object given * to the converter * @returns A newly constructed V3D object converted * from the PyObject. */ Kernel::Matrix<double> PyObjectToMatrix::operator()() { if (m_alreadyMatrix) { return extract<Kernel::Matrix<double>>(m_obj)(); } PyArrayObject *ndarray = (PyArrayObject *)PyArray_View( (PyArrayObject *)m_obj.ptr(), PyArray_DescrFromType(NPY_DOUBLE), &PyArray_Type); const auto shape = PyArray_DIMS(ndarray); npy_intp nx(shape[0]), ny(shape[1]); Kernel::Matrix<double> matrix(nx, ny); for (npy_intp i = 0; i < nx; i++) { auto row = matrix[i]; for (npy_intp j = 0; j < ny; j++) { row[j] = *((double *)PyArray_GETPTR2(ndarray, i, j)); } } return matrix; }
box table_box_rep::adjust_kerning (int mode, double factor) { (void) mode; int n= N(bs), i, j; array<box> adj (n); array<SI> cdw (n); for (i=0; i<n; i++) { SI l, r; adj[i]= bs[i]->adjust_kerning (TABLE_CELL, factor); bs[i]->get_cell_extents (l, r); SI w1= r - l; adj[i]->get_cell_extents (l, r); SI w2= r - l; cdw[i]= w2 - w1; } SI dx= 0; array<SI> nx (n); for (j=0; j<cols; j++) { for (i=0; i<rows; i++) nx[i*cols+j]= x[i*cols+j] + dx; SI dw= MINUS_INFINITY; for (i=0; i<rows; i++) dw= max (dw, cdw[i*cols+j]); dx += dw; for (i=0; i<rows; i++) { int k= i*cols + j; string ha= halign[k]; SI d= dw - cdw[k]; SI cdx= 0; if (ha[0] == 'l') cdx= 0; if (ha[0] == 'r') cdx= d; if (ha[0] == 'c') cdx= d >> 1; adj[k]= adj[k]->adjust_cell_geometry (cdx, 0, dw); } } return table_box (ip, adj, nx, y, halign, cols); }
bool Sol_MultigridPressure3DBase::initialize_base_storage(int nx_val, int ny_val, int nz_val, double hx_val, double hy_val, double hz_val) { // pre-validate if (!check_float(hx_val) || !check_float(hy_val) || !check_float(hz_val)) { printf("[ERROR] Sol_MultigridPressure3DBase::initialize_storage - garbage hx,hy,hz value %f %f %f\n", hx_val, hy_val, hz_val); return false; } // do allocation and initialization _num_levels = num_levels(nx_val, ny_val, nz_val); _h = new double[_num_levels]; _dim = new int3[_num_levels]; _h[0] = min3(hx_val, hy_val, hz_val); _fx = (_h[0] * _h[0]) / (hx_val * hx_val); _fy = (_h[0] * _h[0]) / (hy_val * hy_val); _fz = (_h[0] * _h[0]) / (hz_val * hz_val); _omega = optimal_omega(_fx, _fy, _fz); _dim[0].x = nx_val; _dim[0].y = ny_val; _dim[0].z = nz_val; int level; for (level=1; level < _num_levels; level++) { int this_nx = nx(level-1)/2; int this_ny = ny(level-1)/2; int this_nz = nz(level-1)/2; _h[level] = get_h(level-1)*2; _dim[level].x = this_nx; _dim[level].y = this_ny; _dim[level].z = this_nz; } return true; }
image::vector<3,float> operator()(const image::vector<3,float>& x0) const { image::vector<3,float> nx(x0); nx.normalize(); image::vector<3,float> sum; for (unsigned int j = 0;j < b_vec.size();++j) { float prod = b_vec[j]*nx; float temp = std::cos(prod)-boost::math::sinc_pi(prod); if (std::abs(prod) < 0.0000001) prod = prod > 0.0 ? 0.0000001:-0.0000001; prod = temp/prod; prod *= signal[j]; image::vector<3,float> b_vec_ortho(b_vec[j]); image::vector<3,float> b_proj(nx); b_proj *= (b_vec_ortho*nx); b_vec_ortho -= b_proj; b_vec_ortho *= prod; sum += b_vec_ortho; } sum /= b_vec.size(); return sum; }
void Board::set_miai(int s, int x, int y) { reply[nx(s)][x] = y; reply[nx(s)][y] = x; }
bool Assign<std::string>::do_assign(std::string& dest, int type, const void* data) { char buf[32]; if (isSpecial(type)) { if (isString(type)) { dest.assign((const char*)data,size(type)); return true; } switch (type) { case Null: dest.clear(); return true; case Enum: snprintf(buf,sizeof(buf),"%d",*(const int*)data); dest = buf; return true; case ID: snprintf(buf,sizeof(buf),"0x%016llx",*(const long long*)data); dest = buf; return true; } } else if (isMatrix(type)) { std::string str; dest = "{"; for (int y=0;y<ny(type);y++) { if (y) dest += ", "; dest += '{'; for (int x=0;x<nx(type);x++) { if (x) dest += ", "; do_assign(str, toSingle(type), data); data = ((const char*)data) + elemSize(type); dest += str; } dest += '}'; } dest += '}'; } else if (isVector(type)) { std::string str; dest = "{"; for (int x=0;x<nx(type);x++) { if (x) dest += ", "; do_assign(str, toSingle(type), data); data = ((const char*)data) + elemSize(type); dest += str; } dest += '}'; } else { if (!isSingle(type)) type = toSingle(type); switch (toSingle(type)) { case Bool: dest = (*(const unsigned char*)data)?"true":"false"; return true; case Byte: snprintf(buf,sizeof(buf),"%u",(unsigned)*(const unsigned char*)data); dest = buf; return true; case Short: snprintf(buf,sizeof(buf),"%d",(int)*(const short*)data); dest = buf; return true; case Int: snprintf(buf,sizeof(buf),"%d",*(const int*)data); dest = buf; return true; case QWord: snprintf(buf,sizeof(buf),"%lld",*(const long long*)data); dest = buf; return true; case Float: snprintf(buf,sizeof(buf),"%f",(double)*(const float*)data); dest = buf; return true; case Double: snprintf(buf,sizeof(buf),"%f",*(const double*)data); dest = buf; return true; case LongDouble: snprintf(buf,sizeof(buf),"%Lf",*(const long double*)data); dest = buf; return true; } } // Failure // In this implementation: only Type::Delete is not supported return false; }
/* Algorithm: J.B. Bednar & T.L. Watt (1985), Calculating the Complex Cepstrum without Phase Unwrapping or Integration, IEEE Trans. on ASSP 33, 1014-1017 (Does not work yet). */ Cepstrum Sound_to_Cepstrum_bw (Sound me) { try { long nfft = 2; while (nfft < my nx) { nfft *= 2; } double qmax = (my xmax - my xmin) * nfft / my nx; autoCepstrum thee = Cepstrum_create (qmax, nfft); autoNUMvector<double> x (1, nfft); autoNUMvector<double> nx (1, nfft); for (long i = 1; i <= my nx; i++) { x[i] = my z[1][i]; nx[i] = (i - 1) * x[i]; } // Step 1: Fourier transform x(n) -> X(f) // and n*x(n) -> NX(f) NUMforwardRealFastFourierTransform (x.peek() , nfft); NUMforwardRealFastFourierTransform (nx.peek(), nfft); // Step 2: Multiply {X^*(f) * NX(f)} / |X(f)|^2 // Compute Avg (ln |X(f)|) as Avg (ln |X(f)|^2) / 2. // Treat i=1 separately: x[1] * nx[1] / |x[1]|^2 double lnxa = 0; if (x[1] != 0) { lnxa = 2 * log (fabs (x[1])); x[1] = nx[1] / x[1]; } if (x[2] != 0) { lnxa = 2 * log (fabs (x[2])); x[2] = nx[2] / x[2]; } for (long i = 3; i < nfft; i += 2) { double xr = x[i], nxr = nx[i]; double xi = x[i + 1], nxi = nx[i + 1]; double xa = xr * xr + xi * xi; if (xa > 0) { x[i] = (xr * nxr + xi * nxi) / xa; x[i + 1] = (xr * nxi - xi * nxr) / xa; lnxa += log (xa); } else { x[i] = x[i + 1] = 0; } } lnxa /= 2 * nfft / 2; // Step 4: Inverse transform of complex array x // results in: n * xhat (n) NUMreverseRealFastFourierTransform (x.peek(), nfft); // Step 5: Inverse fft-correction factor: 1/nfftd2 // Divide n * xhat (n) by n for (long i = 2; i <= my nx; i++) { thy z[1][i] = x[i] / ( (i - 1) * nfft); } // Step 6: xhat[0] = Avg (ln |X(f)|) thy z[1][1] = lnxa; return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": no Cepstrum created."); } }
int proc_sign(const ts::wstrings_c & pars) { if (pars.size() < 3) return 0; ts::wstr_c arch = pars.get(1); ts::fix_path( arch, FNO_SIMPLIFY ); ts::wstr_c proc = pars.get(2); ts::fix_path( proc, FNO_SIMPLIFY ); if (!is_file_exists(arch.as_sptr())) { Print(FOREGROUND_RED, "arch file not found: %s\n", to_str(arch).cstr()); return 0; } if (!is_file_exists(proc.as_sptr())) { Print(FOREGROUND_RED, "proc file not found: %s\n", to_str(proc).cstr()); return 0; } ts::buf_c b; b.load_from_disk_file(arch); int archlen = b.size(); ts::md5_c md5; md5.update(b.data(), b.size()); md5.done(); ts::abp_c bp; b.load_from_disk_file(proc); bp.load(b.cstr()); ts::wstr_c procpath = ts::fn_get_path(proc); auto pa = [&]( ts::asptr p ) ->ts::wstr_c { return ts::fn_join(procpath, to_wstr(bp.get_string(p))); }; b.load_from_disk_file( pa(CONSTASTR("ver")) ); ts::str_c ver = b.cstr(); ver.replace_all('/','.').trim(); ts::str_c ss(CONSTASTR("ver=")); ss.append( ver ); ss.append(CONSTASTR("\r\nurl=")); ts::str_c path = bp.get_string(CONSTASTR("path")); path.replace_all(CONSTASTR("%ver%"), ver); path.replace_all(CONSTASTR("%https%"), CONSTASTR("https://")); path.replace_all(CONSTASTR("%http%"), CONSTASTR("http://")); path.appendcvt(ts::fn_get_name_with_ext(arch)); ss.append(path); ss.append(CONSTASTR("\r\nsize=")); ss.append_as_uint(archlen); ss.append(CONSTASTR("\r\nmd5=")); ss.append_as_hex(md5.result(), 16); unsigned char pk[crypto_sign_PUBLICKEYBYTES]; unsigned char sk[crypto_sign_SECRETKEYBYTES]; b.clear(); b.load_from_disk_file( pa(CONSTASTR("sk")) ); if (b.size() != crypto_sign_SECRETKEYBYTES) { rebuild: crypto_sign_keypair(pk, sk); FILE *f = _wfopen(pa(CONSTASTR("sk")), L"wb"); fwrite(sk, 1, sizeof(sk), f); fclose(f); ts::str_c spk; for(int i=0;i<crypto_sign_PUBLICKEYBYTES;++i) spk.append(CONSTASTR("0x")).append_as_hex(pk[i]).append(CONSTASTR(", ")); spk.trunc_length(2); f = _wfopen(pa(CONSTASTR("pk")), L"wb"); fwrite(spk.cstr(), 1, spk.get_length(), f); fclose(f); } else { memcpy(sk, b.data(), crypto_sign_SECRETKEYBYTES); crypto_sign_ed25519_sk_to_pk(pk, sk); b.load_from_disk_file( pa(CONSTASTR("pk")) ); ts::token<char> t(b.cstr(), ','); int n = 0; for(;t; ++t, ++n) { if (n >= sizeof(pk)) goto rebuild; ts::str_c nx(*t); nx.trim(); if (pk[n] != (byte)nx.as_uint()) goto rebuild; } if (n < sizeof(pk)) goto rebuild; } unsigned char sig[crypto_sign_BYTES]; unsigned long long siglen; crypto_sign_detached(sig,&siglen, (const byte *)ss.cstr(), ss.get_length(), sk); ss.append(CONSTASTR("\r\nsign=")); ss.append_as_hex(sig, (int)siglen); if (CONSTASTR("github") == bp.get_string(CONSTASTR("wiki"))) { ss.insert(0,CONSTASTR("[begin]\r\n")); ss.replace_all(CONSTASTR("\r\n"), CONSTASTR("`<br>\r\n`")); ss.replace_all(CONSTASTR("[begin]`"), CONSTASTR("[begin]")); ss.append(CONSTASTR("`<br>\r\n[end]<br>\r\n")); } FILE *f = _wfopen(pa(CONSTASTR("result")), L"wb"); fwrite(ss.cstr(), 1, ss.get_length(), f); fclose(f); return 0; }
//--------------------------------------------------------- void CurvedINS2D::INSLiftDrag2D(double ra) //--------------------------------------------------------- { // function [Cd, Cl, dP, sw, stri] = INSLiftDrag2D(Ux, Uy, PR, ra, nu, time, tstep, Nsteps) // Purpose: compute coefficients of lift, drag and pressure drop at cylinder static FILE* fid; static DVec sw1, sw2; static int Nc=0, stri1=0, stri2=0; if (1 == tstep) { char buf[50]; sprintf(buf, "liftdraghistory%d.dat", N); fid = fopen(buf, "w"); fprintf(fid, "timeCdCldP = [...\n"); // Sample location and weights for pressure drop // Note: the VolkerCylinder test assumes the 2 // sample points (-ra, 0), (ra, 0), are vertices // located on the internal cylinder boundary Sample2D(-ra, 0.0, sw1, stri1); Sample2D( ra, 0.0, sw2, stri2); Nc = mapC.size()/Nfp; } bool bDo=false; if (1==tstep || tstep==Nsteps || !umMOD(tstep,10)) { bDo=true; } else if (time > 3.90 && time < 3.96) { bDo=true; } // catch C_d (3.9362) else if (time > 5.65 && time < 5.73) { bDo=true; } // catch C_l (5.6925) else if (time > 7.999) { bDo=true; } // catch dP (8.0) if (!bDo) return; DVec PRC, nxC, nyC, wv, tv; DMat dUxdx,dUxdy, dUydx,dUydy, MM1D, V1D; DMat dUxdxC,dUxdyC, dUydxC,dUydyC, hforce, vforce, sJC; double dP=0.0, Cd=0.0, Cl=0.0; dP = sw1.inner(PR(All,stri1)) - sw2.inner(PR(All,stri2)); // compute derivatives Grad2D(Ux, dUxdx,dUxdy); dUxdxC=dUxdx(vmapC); dUxdyC=dUxdy(vmapC); Grad2D(Uy, dUydx,dUydy); dUydxC=dUydx(vmapC); dUydyC=dUydy(vmapC); PRC=PR(vmapC); nxC=nx(mapC); nyC=ny(mapC); sJC=sJ(mapC); hforce = -PRC.dm(nxC) + nu*( nxC.dm( 2.0 *dUxdxC) + nyC.dm(dUydxC+dUxdyC) ); vforce = -PRC.dm(nyC) + nu*( nxC.dm(dUydxC+dUxdyC) + nyC.dm( 2.0 *dUydyC) ); hforce.reshape(Nfp, Nc); vforce.reshape(Nfp, Nc); sJC .reshape(Nfp, Nc); // compute weights for integrating (1,hforce) and (1,vforce) V1D = Vandermonde1D(N, r(Fmask(All,1))); MM1D = trans(inv(V1D)) / V1D; wv = MM1D.col_sums(); tv = wv*(sJC.dm(hforce)); Cd=tv.sum(); // Compute drag coefficient tv = wv*(sJC.dm(vforce)); Cl=tv.sum(); // Compute lift coefficient // Output answers for plotting fprintf(fid, "%15.14f %15.14f %15.14f %15.14f;...\n", time, Cd/ra, Cl/ra, dP); fflush(fid); // LOG report if (1==tstep || tstep==Nsteps || !umMOD(tstep,Nreport)) { umLOG(1, "%7d %6.3lf %9.5lf %10.6lf %9.5lf\n", tstep, time, Cd/ra, Cl/ra, dP); } if (tstep==Nsteps) { fprintf(fid, "];\n"); fclose(fid); fid=NULL; } }
int main (int argc, char *argv[]) { Log log; FILE *inFp = 0; FILE *outFp = 0; mxml_node_t *outTree = 0; // hold the xml input to ICAT mxml_node_t *inTree = 0; // Hold the parameter list try { // Check if my assumption of type size are correct. // ************************************************ if(sizeof(short) != 2 || sizeof(int) != 4 ) log.set("Compiler Test", "The integer sizes are not as expected", "(short 2 bytes; int 4 bytes)").printLevel(NXING_LOG_WARNING); if(sizeof(float) != 4 ||sizeof(double) != 8) log.set("Compiler Test", "The float sizes are not as expected", "(float 4 bytes; double 8 bytes)").printLevel(NXING_LOG_WARNING); char mappingFl[NXING_BIG_SIZE] = ""; char nexusFl[NXING_BIG_SIZE] = ""; char outputFl[NXING_BIG_SIZE] = ""; if(argc < 3) { throw log.set("main", "Not enough input parameters!", "Needs 2 input files, mapping file and the NeXus file.", "And one output file.", NXING_ERR_WRONG_INPUT); } else { if(argv[1] != 0) strcpy(mappingFl, argv[1]); if(argv[2] != 0) strcpy(nexusFl, argv[2]); if(argv[3] != 0) strcpy(outputFl, argv[3]); else strcpy(outputFl, "output.xml"); } log.set("main", "input - mapping", mappingFl).printLevel(NXING_LOG_NORMAL); log.set("main", "input - nexus ", nexusFl).printLevel(NXING_LOG_NORMAL); log.set("main", "input - output ", outputFl).printLevel(NXING_LOG_NORMAL); // Read input XML Parameters. // **************************' #ifndef MXML_WRAP mxmlSetWrapMargin(0); #endif inFp = fopen(mappingFl, "r"); if( inFp == 0 ) throw log.set("main", "Can't open the parameter file!", mappingFl, "", NXING_ERR_CANT_OPEN_PARAM); mxml_node_t *inNode; // hold the node to read from. inTree = mxmlLoadFile(NULL, inFp, MXML_TEXT_CALLBACK); fclose(inFp); inFp = 0; if(inTree != 0) log.set("main", "The mapping file has been read!", mappingFl).printLevel(NXING_LOG_ALL); // Create XML output to ICAT. // ************************** outFp = fopen(outputFl, "w"); if( outFp == 0 ) throw log.set("main", "Can't open the output file!", outputFl, "", NXING_ERR_CANT_OPEN_OUTPUT); if(inTree->type == MXML_ELEMENT && (strncmp(inTree->value.element.name, "?xml", 4) == 0)){ outTree = mxmlNewElement(MXML_NO_PARENT, inTree->value.element.name); } log.set("main", "Output Created, first tag added!", inTree->value.element.name).printLevel(NXING_LOG_DEBUG); // // Open the neXus file. // ******************** NxClass nx(nexusFl); //if(nx.isNotOK) throw log.set("Can't open the neXus file!", nexusFl, nx.status); log.set("main", "NeXµs file read!", nexusFl, "", nx.status).printLevel(NXING_LOG_DEBUG); /* * Parse the parameter file, read the neXus file and populate the XML output. */ log.set("main", "Parsing the mapping file!").printLevel(NXING_LOG_DEBUG); inNode = mxmlWalkNext(inTree, inTree, MXML_DESCEND); parseXml(inNode, &outTree, nx); /* * Save the output file */ mxmlSaveFile(outTree, outFp, whitespace_cb); log.set("main", "Output file Saved!", outputFl).printLevel(NXING_LOG_DEBUG); /* * Close the files */ fclose(outFp); /* * Delete the xml Trees */ mxmlDelete(inTree); mxmlDelete(outTree); exit(0); } catch(Log log) { log.printLevel(NXING_LOG_ERROR); if(inFp != 0) fclose(inFp); if(outFp != 0) fclose(outFp); if(inTree != 0) mxmlDelete(inTree); if(outTree != 0) mxmlDelete(outTree); exit(0); } }
//-------------------------------------------------------------------------- //-------- execute --------------------------------------------------------- //-------------------------------------------------------------------------- void AssembleMomentumElemSymmetrySolverAlgorithm::execute() { stk::mesh::BulkData & bulk_data = realm_.bulk_data(); stk::mesh::MetaData & meta_data = realm_.meta_data(); const int nDim = meta_data.spatial_dimension(); // space for LHS/RHS; nodesPerElem*nDim*nodesPerElem*nDim and nodesPerElem*nDim std::vector<double> lhs; std::vector<double> rhs; std::vector<int> scratchIds; std::vector<double> scratchVals; std::vector<stk::mesh::Entity> connected_nodes; // vectors std::vector<double> nx(nDim); // pointers to fixed values double *p_nx = &nx[0]; // nodal fields to gather std::vector<double> ws_velocityNp1; std::vector<double> ws_coordinates; std::vector<double> ws_viscosity; // master element std::vector<double> ws_face_shape_function; std::vector<double> ws_dndx; std::vector<double> ws_det_j; // deal with state VectorFieldType &velocityNp1 = velocity_->field_of_state(stk::mesh::StateNP1); // define vector of parent topos; should always be UNITY in size std::vector<stk::topology> parentTopo; // define some common selectors stk::mesh::Selector s_locally_owned_union = meta_data.locally_owned_part() &stk::mesh::selectUnion(partVec_); stk::mesh::BucketVector const& face_buckets = realm_.get_buckets( meta_data.side_rank(), s_locally_owned_union ); for ( stk::mesh::BucketVector::const_iterator ib = face_buckets.begin(); ib != face_buckets.end() ; ++ib ) { stk::mesh::Bucket & b = **ib ; // extract connected element topology b.parent_topology(stk::topology::ELEMENT_RANK, parentTopo); ThrowAssert ( parentTopo.size() == 1 ); stk::topology theElemTopo = parentTopo[0]; // volume master element MasterElement *meSCS = realm_.get_surface_master_element(theElemTopo); const int nodesPerElement = meSCS->nodesPerElement_; // face master element MasterElement *meFC = realm_.get_surface_master_element(b.topology()); const int nodesPerFace = meFC->nodesPerElement_; const int numScsBip = meFC->numIntPoints_; // resize some things; matrix related const int lhsSize = nodesPerElement*nDim*nodesPerElement*nDim; const int rhsSize = nodesPerElement*nDim; lhs.resize(lhsSize); rhs.resize(rhsSize); scratchIds.resize(rhsSize); scratchVals.resize(rhsSize); connected_nodes.resize(nodesPerElement); // algorithm related; element ws_velocityNp1.resize(nodesPerElement*nDim); ws_coordinates.resize(nodesPerElement*nDim); ws_viscosity.resize(nodesPerFace); ws_face_shape_function.resize(numScsBip*nodesPerFace); ws_dndx.resize(nDim*numScsBip*nodesPerElement); ws_det_j.resize(numScsBip); // pointers double *p_lhs = &lhs[0]; double *p_rhs = &rhs[0]; double *p_velocityNp1 = &ws_velocityNp1[0]; double *p_coordinates = &ws_coordinates[0]; double *p_viscosity = &ws_viscosity[0]; double *p_face_shape_function = &ws_face_shape_function[0]; double *p_dndx = &ws_dndx[0]; // shape function meFC->shape_fcn(&p_face_shape_function[0]); const stk::mesh::Bucket::size_type length = b.size(); for ( stk::mesh::Bucket::size_type k = 0 ; k < length ; ++k ) { // zero lhs/rhs for ( int p = 0; p < lhsSize; ++p ) p_lhs[p] = 0.0; for ( int p = 0; p < rhsSize; ++p ) p_rhs[p] = 0.0; // get face stk::mesh::Entity face = b[k]; //====================================== // gather nodal data off of face //====================================== stk::mesh::Entity const * face_node_rels = bulk_data.begin_nodes(face); int num_face_nodes = bulk_data.num_nodes(face); // sanity check on num nodes ThrowAssert( num_face_nodes == nodesPerFace ); for ( int ni = 0; ni < num_face_nodes; ++ni ) { stk::mesh::Entity node = face_node_rels[ni]; // gather scalars p_viscosity[ni] = *stk::mesh::field_data(*viscosity_, node); } // pointer to face data const double * areaVec = stk::mesh::field_data(*exposedAreaVec_, face); // extract the connected element to this exposed face; should be single in size! stk::mesh::Entity const * face_elem_rels = bulk_data.begin_elements(face); ThrowAssert( bulk_data.num_elements(face) == 1 ); // get element; its face ordinal number stk::mesh::Entity element = face_elem_rels[0]; const stk::mesh::ConnectivityOrdinal* face_elem_ords = bulk_data.begin_element_ordinals(face); const int face_ordinal = face_elem_ords[0]; // mapping from ip to nodes for this ordinal const int *ipNodeMap = meSCS->ipNodeMap(face_ordinal); //========================================== // gather nodal data off of element //========================================== stk::mesh::Entity const * elem_node_rels = bulk_data.begin_nodes(element); int num_nodes = bulk_data.num_nodes(element); // sanity check on num nodes ThrowAssert( num_nodes == nodesPerElement ); for ( int ni = 0; ni < num_nodes; ++ni ) { stk::mesh::Entity node = elem_node_rels[ni]; // set connected nodes connected_nodes[ni] = node; // gather vectors double * uNp1 = stk::mesh::field_data(velocityNp1, node); double * coords = stk::mesh::field_data(*coordinates_, node); const int offSet = ni*nDim; for ( int j=0; j < nDim; ++j ) { p_velocityNp1[offSet+j] = uNp1[j]; p_coordinates[offSet+j] = coords[j]; } } // compute dndx double scs_error = 0.0; meSCS->face_grad_op(1, face_ordinal, &p_coordinates[0], &p_dndx[0], &ws_det_j[0], &scs_error); // loop over boundary ips for ( int ip = 0; ip < numScsBip; ++ip ) { const int nearestNode = ipNodeMap[ip]; // offset for bip area vector and types of shape function const int faceOffSet = ip*nDim; const int offSetSF_face = ip*nodesPerFace; // form unit normal double asq = 0.0; for ( int j = 0; j < nDim; ++j ) { const double axj = areaVec[faceOffSet+j]; asq += axj*axj; } const double amag = std::sqrt(asq); for ( int i = 0; i < nDim; ++i ) { p_nx[i] = areaVec[faceOffSet+i]/amag; } // interpolate to bip double viscBip = 0.0; for ( int ic = 0; ic < nodesPerFace; ++ic ) { const double r = p_face_shape_function[offSetSF_face+ic]; viscBip += r*p_viscosity[ic]; } //================================ // diffusion second //================================ for ( int ic = 0; ic < nodesPerElement; ++ic ) { const int offSetDnDx = nDim*nodesPerElement*ip + ic*nDim; for ( int j = 0; j < nDim; ++j ) { const double axj = areaVec[faceOffSet+j]; const double dndxj = p_dndx[offSetDnDx+j]; const double uxj = p_velocityNp1[ic*nDim+j]; const double divUstress = 2.0/3.0*viscBip*dndxj*uxj*axj*includeDivU_; for ( int i = 0; i < nDim; ++i ) { // matrix entries int indexR = nearestNode*nDim + i; int rowR = indexR*nodesPerElement*nDim; const double dndxi = p_dndx[offSetDnDx+i]; const double uxi = p_velocityNp1[ic*nDim+i]; const double nxi = p_nx[i]; const double nxinxi = nxi*nxi; // -mu*dui/dxj*Aj*ni*ni; sneak in divU (explicit) double lhsfac = - viscBip*dndxj*axj*nxinxi; p_lhs[rowR+ic*nDim+i] += lhsfac; p_rhs[indexR] -= lhsfac*uxi + divUstress*nxinxi; // -mu*duj/dxi*Aj*ni*ni lhsfac = - viscBip*dndxi*axj*nxinxi; p_lhs[rowR+ic*nDim+j] += lhsfac; p_rhs[indexR] -= lhsfac*uxj; // now we need the +nx*ny*Fy + nx*nz*Fz part for ( int l = 0; l < nDim; ++l ) { if ( i != l ) { const double nxinxl = nxi*p_nx[l]; const double uxl = p_velocityNp1[ic*nDim+l]; const double dndxl = p_dndx[offSetDnDx+l]; // -ni*nl*mu*dul/dxj*Aj; sneak in divU (explict) lhsfac = -viscBip*dndxj*axj*nxinxl; p_lhs[rowR+ic*nDim+l] += lhsfac; p_rhs[indexR] -= lhsfac*uxl + divUstress*nxinxl; // -ni*nl*mu*duj/dxl*Aj lhsfac = -viscBip*dndxl*axj*nxinxl; p_lhs[rowR+ic*nDim+j] += lhsfac; p_rhs[indexR] -= lhsfac*uxj; } } } } } } apply_coeff(connected_nodes, scratchIds, scratchVals, rhs, lhs, __FILE__); } } }
/* Render Modes are * -Vertex Color Interpolation * -Texture Mapping * Renders the triangle mess, shades using the sence lights. * Shadow Mapping implimented */ void TMesh::RenderFilled(PPC *ppc, FrameBuffer *fb, unsigned int color, int lightsN, Light **L, float ka, FrameBuffer *texture, enviromap *cube, int renderMode) { //Project vertices on to the camera vector *pverts = new vector[vertsN]; for (int vi = 0; vi < vertsN; vi++) { ppc->Project(verts[vi], pverts[vi]); } for (int tri = 0; tri < trisN; tri++) { int vinds[3]; vinds[0] = tris[tri*3+0]; vinds[1] = tris[tri*3+1]; vinds[2] = tris[tri*3+2]; if( pverts[vinds[0]][2] == FLT_MAX || pverts[vinds[1]][2] == FLT_MAX || pverts[vinds[2]][2] == FLT_MAX ) continue; //Compute bounding box aabb of projected vertices AABB aabb(pverts[vinds[0]]); aabb.AddPoint(pverts[vinds[1]]); aabb.AddPoint(pverts[vinds[2]]); //Clip aabb with frame if(!aabb.Clip(0.0f, (float) fb->w, 0.0f, (float) fb->h)) continue; int left = (int)(aabb.corners[0][0] + 0.5f); int right = (int)(aabb.corners[1][0] - 0.5f); int top = (int)(aabb.corners[0][1] + 0.5f); int bottom = (int)(aabb.corners[1][1] - 0.5f); vector red( cols[vinds[0]][0], cols[vinds[1]][0], cols[vinds[2]][0]); vector green( cols[vinds[0]][1], cols[vinds[1]][1], cols[vinds[2]][1]); vector blue( cols[vinds[0]][2], cols[vinds[1]][2], cols[vinds[2]][2]); vector depth( pverts[vinds[0]][2], pverts[vinds[1]][2], pverts[vinds[2]][2] ); vector rABC, gABC, bABC, zABC, nxABC, nyABC, nzABC, sABC, tABC; vector DEF; vector eeqs[3]; SetEEQS( pverts[vinds[0]], pverts[vinds[1]], pverts[vinds[2]], eeqs); matrix ptm(pverts[vinds[0]], pverts[vinds[1]], pverts[vinds[2]]); ptm.setCol(2, vector(1.0f, 1.0f, 1.0f)); ptm = invert(ptm); // Set up for normals vector nx( normals[vinds[0]][0], normals[vinds[1]][0], normals[vinds[2]][0] ); vector ny( normals[vinds[0]][1], normals[vinds[1]][1], normals[vinds[2]][1] ); vector nz( normals[vinds[0]][2], normals[vinds[1]][2], normals[vinds[2]][2] ); // Set depth interpolation through screen space interpolation zABC = ptm * depth; //Matrix for Model Space interpolation matrix Q; Q = ComputeRastMatrix(ppc, verts[vinds[0]], verts[vinds[1]], verts[vinds[2]]); DEF = Q[0] + Q[1] + Q[2]; //Compute Model Space interpolation constants SetModelRast(Q, nx, &nxABC); SetModelRast(Q, ny, &nyABC); SetModelRast(Q, nz, &nzABC); //SetModelRast(Q, depth, &zABC); if( renderMode == VCI ) { // Setup screen space linear variation of color rABC = ptm * red; gABC = ptm * green; bABC = ptm * blue; }else if( renderMode == MCI ) { // Set Color Model Space Constants SetModelRast(Q, red, &rABC); SetModelRast(Q, green, &gABC); SetModelRast(Q, blue, &bABC); }else if( renderMode == TM) { //Get texture model space parameters vector s( tcs[2*vinds[0]+0], tcs[2*vinds[1]+0], tcs[2*vinds[2]+0]); vector t( tcs[2*vinds[0]+1], tcs[2*vinds[1]+1], tcs[2*vinds[2]+1]); SetModelRast(Q, s, &sABC); SetModelRast(Q, t, &tABC); } for( int v = top; v <= bottom; v++ ){ for ( int u = left; u <= right; u++ ) { if(fb->IsOutsideFrame(u,v)) continue; vector pv((float)u+0.5f, (float)v+0.5f, 1.0f); //Check whether pixel is inside triangle if (eeqs[0]*pv < 0.0f || eeqs[1]*pv < 0.0f || eeqs[2]*pv < 0.0f) continue; // Check whether triangle is closer than what was previously // seen at this pixel float currz = zABC * pv; //currz /= (DEF * pv); if (fb->IsFarther(u, v, currz)) continue; fb->SetZ(u, v, currz); // pixel is inside triangle and triangle is visible at pixel // compute color of pixel based on current triangle vector currColor; if ( renderMode == SM) continue; if ( renderMode == VCI ){ currColor = vector( rABC * pv, gABC * pv, bABC * pv ); }else if ( renderMode == MCI ) { float r = ModelInterpolation(u, v, rABC, DEF); float g = ModelInterpolation(u, v, gABC, DEF); float b = ModelInterpolation(u, v, bABC, DEF); currColor = vector(r,g,b); } if ( renderMode == TM) { int w = texture->w; int h = texture->h; float miS = ModelInterpolation(u, v, sABC, DEF); float miT = ModelInterpolation(u, v, tABC, DEF); miS = (miS * (float)w); miT = (miT * (float)h); int st = (h-1-(int)(miT)%h) * w+(int)(miS)%w; if(st < 0 || st > h*w) continue; currColor.SetFromColor(texture->pix[st]); } vector currNormal = vector(nxABC*pv/(DEF*pv), nyABC*pv/(DEF*pv), nzABC*pv/(DEF*pv)).norm(); if ( renderMode == RFL ) { vector eye = ppc->C; vector P = ppc->UnProject(pv); vector ev = (eye - P); vector rv = currNormal*(currNormal*ev)*2.0f - ev; rv = rv.norm(); //currColor = (rv + vector(1.0f, 1.0f, 1.0f))/2.0f; currColor.SetFromColor(cube->getColor(rv)); } //Calculated Color at pixel using phong equation for( int li = 0; li < lightsN; li++ ){ if(!L[li]->on) continue; vector fullColor; fullColor.SetFromColor(color); vector lv; vector pp(pv); pp[2] = currz; lv = (L[li]->L->C - ppc->UnProject(pp)).norm(); float kd = lv * currNormal; kd = (kd < 0.0f) ? 0.0f : kd; //currColor = currColor * ka ; //currColor = currColor * (ka + (1.0f-ka)*kd); vector point = ppc->UnProject(pp); vector SMp; L[li]->L->Project(point, SMp); float ul = SMp[0]; float vl = SMp[1]; if(L[li]->sm->IsOutsideFrame(ul, vl)) { currColor = currColor * ka ; //fb->Set(u,v, currColor.GetColor()); continue; } //Check depth from light to calculate shadows float e = SMp[2]*.01; if(L[li]->sm->IsFarther((int)ul, (int)vl, SMp[2]+e)) { currColor = currColor * ka ; //fb->Set(u,v, currColor.GetColor()); }else { currColor *= ka +(1.0f-ka)*kd; //fb->Set(u,v, currColor.GetColor()); } } fb->Set(u,v, currColor.GetColor()); } } } delete []pverts; }
bool Board::not_in_miai(Move mv) { return reply[nx(mv.s)][mv.lcn]==mv.lcn ; }
double kraskov_mutual_information(int k, const vector<double> &X, const vector<double> &Y) { //Create a 2D grid for the x, y points if (X.size() != Y.size()) { std::cout<<" Error('X and Y must contain the same number of samples')"<<std::endl; } int nObs = X.size(); double max_X = 1.0; //Assumption: since sigmoid values always range between 0-1 double min_X = 0.0; //Assumption: since sigmoid values always range between 0-1 //dz = zeros(nObs, nObs); //dx = zeros(nObs, nObs); //dy = zeros(nObs, nObs); //Divide the space into a 2-D square grid of size (k/N)^(1/2) //Store values/pointers of X/Y values of the random variables double twoD_blocklen = sqrt((double)(k*10)/nObs);// Can be changed after experimentation to suit the data distribution int twoD_numblocks = ceil((max_X-min_X)/twoD_blocklen); twoD_blocklen = (max_X-min_X)/twoD_numblocks; //Update based on the rounded off value of num blocks vector<vector<vector<double> > > twoD_grid(twoD_numblocks, vector<vector<double> >(twoD_numblocks));//2D grid. For each block, list of points inside the block std::vector<std::vector<double> > twoD_gridloc(nObs, vector<double> (2)); //For each point, returns the x, y coordinate of the block int twoDgrid_x_min = 0; int twoDgrid_x_max = twoD_numblocks-1; int twoDgrid_y_min = 0; int twoDgrid_y_max = twoD_numblocks-1; //vector<vector<double> > points_knn(nObs, vector<double> (2));//x, y coordinate of the k-th nearest neighbor vector<double> dist_knn(nObs,-1.0); //Create 1-D grid for x and y variables and compute number of points //in axis which are strictly less than dist_knn(i) apart from x(i) // and y(i) respectively double oneD_slicelen = ((double)50/nObs);// Can be changed after experimentation to suit the data distribution int oneD_numslice = ceil((max_X-min_X)/oneD_slicelen); oneD_slicelen = (max_X-min_X)/oneD_numslice; //Update based on the rounded off value of num blocks vector<vector<double> > oneD_x_grid(oneD_numslice);//1D grid has x locations of the points lying inside each slice of the grid vector<vector<double> > oneD_y_grid(oneD_numslice);//1D grid has y locations of the points lying inside each slice of the grid vector<double> oneD_x_gridloc(nObs);//1D x grid slice location for each point vector<double> oneD_y_gridloc(nObs);//1D y grid slice location for each point int oneDgrid_x_min = 0; int oneDgrid_x_max = oneD_numslice-1; int oneDgrid_y_min = 0; int oneDgrid_y_max = oneD_numslice-1; vector <int> nx(nObs);//Number of x points that are strictly nearer to the point of interest than the knn vector <int> ny(nObs);//Number of y points that are strictly nearer to the point of interest than the knn clock_t start, end, start1, end1; for (int i=0; i<nObs; i++) { //if (X[i] == 1) { // X[i] = X[i] - 0.0000001; //Subtract small number to make sure last block is seleced //} //if (Y[i] == 1){ // Y[i] = Y[i] - 0.0000001; //Subtract small number to make sure last block is selected //} //Create 2D grid int block_x_loc = floor((double)X[i]/twoD_blocklen); //Change ceil to floor for python/c++ int block_y_loc = floor((double)Y[i]/twoD_blocklen); //Change ceil to floor for python/c++ twoD_grid[block_x_loc][block_y_loc].push_back(X[i]); twoD_grid[block_x_loc][block_y_loc].push_back(Y[i]); twoD_gridloc[i][0] = block_x_loc; twoD_gridloc[i][1] = block_y_loc; //Create 1D grid int slice_x_loc = floor((double)X[i]/oneD_slicelen); //Change ceil to floor for python/c++ int slice_y_loc = floor((double)Y[i]/oneD_slicelen); //Change ceil to floor for python/c++ oneD_x_grid[slice_x_loc].push_back(X[i]); oneD_y_grid[slice_y_loc].push_back(Y[i]); oneD_x_gridloc[i] = slice_x_loc; oneD_y_gridloc[i] = slice_y_loc; } //For each point, find the k-th nearest neighbor by checking nearby grids for (int i=0; i<nObs; i++) { bool found_knn = false; bool found_nn = false; int ring_num = 0; int block_x_loc = twoD_gridloc[i][0]; int block_y_loc = twoD_gridloc[i][1]; vector <double> list_nn; vector <double> list_nndist; vector <double> temp_list_nn; vector <double> temp_list_nndist; vector <double> list_of_blocks; //Find the distance to the k nearest neighbor while (found_knn == false) { //Step 1 - Evaluate current ring blocks and find the nearest point list_of_blocks = calc_ring_blocks(block_x_loc, block_y_loc, ring_num, twoDgrid_x_max, twoDgrid_x_min, twoDgrid_y_max, twoDgrid_y_min); found_nn = twoD_nearest_neighbor(temp_list_nn, temp_list_nndist, list_of_blocks, X[i], Y[i], twoD_grid,k); if(found_nn){ list_nn.insert(list_nn.end(), temp_list_nn.begin(), temp_list_nn.end()); list_nndist.insert(list_nndist.end(), temp_list_nndist.begin(), temp_list_nndist.end()); } temp_list_nn.clear(); temp_list_nndist.clear(); //If nearest point found, then validate by going to Step 2. if ((list_nn.size()/2)>=k) { //Step 2 - Validate by going to the next ring. ring_num = ring_num + 1; list_of_blocks = calc_ring_blocks(block_x_loc, block_y_loc, ring_num, twoDgrid_x_max, twoDgrid_x_min, twoDgrid_y_max, twoDgrid_y_min); found_nn = twoD_nearest_neighbor(temp_list_nn, temp_list_nndist, list_of_blocks, X[i], Y[i], twoD_grid,k); if(found_nn) { list_nn.insert(list_nn.end(), temp_list_nn.begin(), temp_list_nn.end()); list_nndist.insert(list_nndist.end(), temp_list_nndist.begin(), temp_list_nndist.end()); } temp_list_nn.clear(); temp_list_nndist.clear(); //Find distance to the kth nearest neighbor int temp_ind; double temp_dist; double large_num = 100.00; for (int j=0; j<k; j++) { temp_ind = min_element( list_nndist.begin(), list_nndist.end() ) - list_nndist.begin(); temp_dist = list_nndist[temp_ind]; list_nndist[temp_ind] = large_num;//Replace smallest element with a large number to find the next smallest } int ind_kth = temp_ind;//Index of the k nearest neighbor dist_knn[i] = temp_dist; ////Create a vector of list_nndist indexes found_knn = true; //********************OLD APPROACH TO FIND DISTANCE TO K-NN********************* ////Create a vector of list_nndist indexes //std::vector<int> ind(list_nndist.size()); //for (int j=0; j<ind.size(); j++) { // ind[j] = j; //} ////Create a pair of list_nndist and its indexes //vector<pair<double,int> > nndist_ind_pair(list_nndist.size()); //for (int j=0; j<ind.size(); j++) { // nndist_ind_pair[j].first = list_nndist[j]; // nndist_ind_pair[j].second = ind[j]; //} //Sort in ascending order of distance //std::sort(nndist_ind_pair.begin(), nndist_ind_pair.end(), sort_pred); //int ind_kth = nndist_ind_pair[k-1].second;//Index of the k nearest neighbor //points_knn[i][0] = list_nn[ind_kth*2]; //x location of k-th nearest point //points_knn[i][1] = list_nn[ind_kth*2+1]; //y location of k-th nearest point //dist_knn[i] = list_nndist[ind_kth]; //********************OLD APPROACH TO FIND DISTANCE TO K-NN********************* } //If no point found, then go to the next ring and go back to Step 1 else{ ring_num = ring_num + 1; } } //Find total number of points on x grid which are strictly less than k nearest distance //apart from the point of interest nx[i] = total_nearby_points(X[i], oneD_x_grid, dist_knn[i], oneDgrid_x_min, oneDgrid_x_max, oneD_slicelen); //%Find points on y grid .... ny[i] = total_nearby_points(Y[i], oneD_y_grid, dist_knn[i], oneDgrid_y_min, oneDgrid_y_max, oneD_slicelen); } double mutual_info = 0.0; double average = 0.0; for (int i=0; i<nx.size(); i++) { average = average + digama(nx[i] + 1); average = average + digama(ny[i] + 1); } average = average/nObs; mutual_info = digama(k) - average + digama(nObs); //psi(k) - sum(psi(nx + 1) + psi(ny + 1)) / nObs + psi(nObs) //If Mutual information is negative, make it zero //Mutual Information can be greater than 1 if (mutual_info < 0.0) { mutual_info = 0.0; } return mutual_info; }
double slow_kraskov_mutual_information(int k, const vector<double> &X, const vector<double> &Y) { if (X.size() != Y.size()) { std::cout<<" Error('X and Y must contain the same number of samples')"<<std::endl; } int nObs = X.size(); vector < vector <double> > dx (nObs, vector <double> (nObs, -1.0)); vector < vector <double> > dy (nObs, vector <double> (nObs, -1.0)); vector < vector <double> > dz (nObs, vector <double> (nObs, -1.0)); vector <int> nx(nObs);//Number of x points that are strictly nearer to the point of interest than the knn vector <int> ny(nObs);//Number of y points that are strictly nearer to the point of interest than the knn vector<double> dist_knn(nObs,-1.0); for (int i = 0; i < nObs; i++) { for (int j = 0; j < nObs; j++) { dx[i][j] = abs(X[i]- X[j]); dy[i][j] = abs(Y[i]- Y[j]); if (dx[i][j] > dy[i][j]) { dz[i][j] =dx[i][j]; } else { dz[i][j] =dy[i][j]; } } } for (int i = 0; i < nObs; i++) { vector <double> dxSample = dx[i]; vector <double> dySample = dy[i]; vector <double> dzSample = dz[i]; dxSample.erase(dxSample.begin() + i); dySample.erase(dySample.begin() + i); dzSample.erase(dzSample.begin() + i); int temp_ind; double temp_dist; double large_num = 100.00; for (int j=0; j<k; j++) { temp_ind = min_element( dzSample.begin(), dzSample.end() ) - dzSample.begin(); temp_dist = dzSample[temp_ind]; dzSample[temp_ind] = large_num;//Replace smallest element with a large number to find the next smallest } int ind_kth = temp_ind;//Index of the k nearest neighbor dist_knn[i] = temp_dist; bool found_flag = false; //X-axis std::sort (dxSample.begin(), dxSample.end(), myfunction); for (int j=0; j < dxSample.size(); j++) { if (dxSample[j]<dist_knn[i]) { nx[i]+= 1; } else { break; } } //Y-axis std::sort (dySample.begin(), dySample.end(), myfunction); for (int j=0; j < dySample.size(); j++) { if (dySample[j]<dist_knn[i]) { ny[i]+= 1; } else { break; } } } double mutual_info = 0.0; double average = 0.0; for (int i=0; i<nx.size(); i++) { average = average + digama(nx[i] + 1); average = average + digama(ny[i] + 1); } average = average/nObs; mutual_info = digama(k) - average + digama(nObs); //psi(k) - sum(psi(nx + 1) + psi(ny + 1)) / nObs + psi(nObs) //If Mutual information is negative, make it zero //Mutual Information can be greater than 1 if (mutual_info < 0.0) { mutual_info = 0.0; } return mutual_info; }
bool Sol_MultigridPressure3DBase::do_vcycle(double tolerance, int max_iter, double &result_l2, double &result_linf) { clear_error(); int level; int coarse_level = _num_levels-1; apply_boundary_conditions(0); double orig_l2=0, orig_linf=0; restrict_residuals(0,0, (convergence & CONVERGENCE_CALC_L2) ? &orig_l2 : 0, (convergence & CONVERGENCE_CALC_LINF) ? &orig_linf : 0); //printf("Error Before: l2 = %f, linf = %f\n", orig_l2, orig_linf); double orig_error = (convergence & CONVERGENCE_CRITERIA_L2) ? orig_l2 : (convergence & CONVERGENCE_CRITERIA_LINF) ? orig_linf : 1e20; if (orig_error < tolerance) { if (convergence & CONVERGENCE_CALC_L2) result_l2 = orig_l2; if (convergence & CONVERGENCE_CALC_LINF) result_linf = orig_linf; return true; } for (int i_cyc = 0; i_cyc < max_iter; i_cyc++) { // going down for (level = 0; level < coarse_level; level++) { relax(level, nu1, RO_RED_BLACK); clear_zero(level+1); apply_boundary_conditions(level+1); if (level == 0) { restrict_residuals(0, 1, (convergence & CONVERGENCE_CALC_L2) ? &result_l2 : 0, (convergence & CONVERGENCE_CALC_LINF) ? &result_linf : 0); double residual = (convergence & CONVERGENCE_CRITERIA_L2) ? result_l2 : (convergence & CONVERGENCE_CRITERIA_LINF) ? result_linf : 1e20; //printf("%d: residual = %.12f\n", i_cyc, result_linf); // if we're below tolerance, or we're no longer converging, bail out if (residual < tolerance) { // last time through, we need to apply boundary condition to u[0], since we just relaxed (above), but haven't propagated changes to ghost cells. // in the case we are not finished, by the time we get back to level 0 (via coarsening & then prolongation), ghost cells would be filled in. // but since we are bailing here, we need to explicitly make ghost cells up-to-date with u. apply_boundary_conditions(0); //printf("[INFO] Sol_MultigridPressure3DBase::do_vcycle - error after %d iterations: L2 = %f (%fx), Linf = %f (%fx)\n", i_cyc, result_l2, orig_l2 / result_l2, result_linf, orig_linf / result_linf); return !any_error(); } } else restrict_residuals(level, level+1, 0, 0); } // these relaxation steps are essentially free, so do lots of them // (reference implementation uses nu1+nu2) - this is probably overkill, i need to revisit this // with a good heuristic. Inhomogeneous conditions require more iterations. int coarse_iters = max3(nx(coarse_level)*ny(coarse_level), ny(coarse_level)*nz(coarse_level), nx(coarse_level)*nz(coarse_level))/2; relax(coarse_level, coarse_iters, make_symmetric_operator ? RO_SYMMETRIC : RO_RED_BLACK); //relax(coarse_level, (nx(coarse_level)*ny(coarse_level)*nz(coarse_level))/2); // going up for (level = coarse_level-1; level >= 0; level--) { prolong(level+1, level); // don't need to relax finest grid since it will get relaxed at the beginning of the next v-cycle if (level > 0) relax(level, nu2, make_symmetric_operator ? RO_BLACK_RED : RO_RED_BLACK); } } if (!(convergence & CONVERGENCE_CRITERIA_NONE)) printf("[WARNING] Sol_MultigridPressure3DBase::do_vcycle - Failed to converge, error after: L2 = %f (%fx), Linf = %f (%fx)\n", result_l2, orig_l2 / result_l2, result_linf, orig_linf / result_linf); return false; }
bool Sol_MultigridPressure3DBase::do_fmg(double tolerance, int max_iter, double &result_l2, double &result_linf) { CPUTimer timer; timer.start(); clear_error(); int level_ncyc; int level; result_l2 = result_linf = 0; apply_boundary_conditions(0); double orig_l2=0, orig_linf=0; restrict_residuals(0,0, (convergence & CONVERGENCE_CALC_L2) ? &orig_l2 : 0, (convergence & CONVERGENCE_CALC_LINF) ? &orig_linf : 0); //printf("Error Before: l2 = %f, linf = %f\n", orig_l2, orig_linf); double orig_error = (convergence & CONVERGENCE_CRITERIA_L2) ? orig_l2 : (convergence & CONVERGENCE_CRITERIA_LINF) ? orig_linf : 1e20; if (orig_error < tolerance) { if (convergence & CONVERGENCE_CALC_L2) result_l2 = orig_l2; if (convergence & CONVERGENCE_CALC_LINF) result_linf = orig_linf; return true; } #if 0 // for testing relaxation only, enable this code block double iter_l2, iter_linf; for (int o=0; o < 100; o++) { relax(0, 10, RO_SYMMETRIC); restrict_residuals(0, 0, &iter_l2, &iter_linf); printf("error: l2 = %.12f, linf = %.12f\n", iter_l2, iter_linf); } printf("reduction: l2 = %f, linf = %f\n", orig_l2/iter_l2, orig_linf/iter_linf); result_l2 = iter_l2; result_linf = iter_linf; return true; #endif // initialize all the residuals. // we need this because in the FMG loop below, we don't necessarily start at level 0, but // rather 2 levels from the finest. Which means we first need to propagate the errors all the way down first before // beginning FMG. int coarse_level = _num_levels-1; int num_vcyc = 0; for (level = 0; level < _num_levels-1; level++) { // initialize U (solution) at next level to zero clear_zero(level+1); apply_boundary_conditions(level+1); // restrict residuals to the next level. restrict_residuals(level, level+1,0,0); } // do the full-multigrid loop for (int fine_level = _num_levels-1; fine_level >= 0 ; fine_level--) { //{ int fine_level = 0; // do a single v-cycle instead // we always do one extra v-cycle level_ncyc = (fine_level == 0) ? max_iter+1 : 1; // do ncyc v-cycle's for (int i_cyc = 0; i_cyc < level_ncyc; i_cyc++) { if (fine_level == 0) num_vcyc++; // going down for (level = fine_level; level < coarse_level; level++) { relax(level, nu1, RO_RED_BLACK); clear_zero(level+1); apply_boundary_conditions(level+1); if (level == 0) { restrict_residuals(0, 1, (convergence & CONVERGENCE_CALC_L2) ? &result_l2 : 0, (convergence & CONVERGENCE_CALC_LINF) ? &result_linf : 0); double residual = (convergence & CONVERGENCE_CRITERIA_L2) ? result_l2 : (convergence & CONVERGENCE_CRITERIA_LINF) ? result_linf : 1e20; if (ThreadManager::this_image() == 0) printf("%d: residual = %.12f,%.12f\n", i_cyc, result_linf, result_l2); // if we're below tolerance, or we're no longer converging, bail out if (residual < tolerance) { // last time through, we need to apply boundary condition to u[0], since we just relaxed (above), but haven't propagated changes to ghost cells. // in the case we are not finished, by the time we get back to level 0 (via coarsening & then prolongation), ghost cells would be filled in. // but since we are bailing here, we need to explicitly make ghost cells up-to-date with u. apply_boundary_conditions(0); timer.stop(); //printf("[ELAPSED] Sol_MultigridPressure3DBase::do_fmg - converged in %fms\n", timer.elapsed_ms()); printf("[INFO] Sol_MultigridPressure3DBase::do_fmg - error after %d iterations: L2 = %f (%fx), Linf = %f (%fx)\n", i_cyc, result_l2, orig_l2 / result_l2, result_linf, orig_linf / result_linf); global_counter_add("vcycles", num_vcyc); return !any_error(); } } else restrict_residuals(level, level+1, 0, 0); } // these relaxation steps are essentially free, so do lots of them // (reference implementation uses nu1+nu2) - this is probably overkill, i need to revisit this // with a good heuristic. Inhomogeneous conditions require more iterations. int coarse_iters = max3(nx(coarse_level)*ny(coarse_level), ny(coarse_level)*nz(coarse_level), nx(coarse_level)*nz(coarse_level))/2; relax(coarse_level, coarse_iters, make_symmetric_operator ? RO_SYMMETRIC : RO_RED_BLACK); //relax(coarse_level, (nx(coarse_level)*ny(coarse_level)*nz(coarse_level))/2); // going up for (level = coarse_level-1; level >= fine_level; level--) { prolong(level+1, level); // don't need to relax finest grid since it will get relaxed at the beginning of the next v-cycle if (level > 0) relax(level, nu2, make_symmetric_operator ? RO_BLACK_RED : RO_RED_BLACK); } } if (fine_level > 0) { // if not at finest level, need to prolong once more to next finer level for the next fine_level value prolong(fine_level, fine_level-1); } } timer.stop(); //printf("[ELAPSED] Sol_MultigridPressure3DBase::do_fmg - stopped iterations after %fms\n", timer.elapsed_ms()); if (!(convergence & CONVERGENCE_CRITERIA_NONE)) printf("[WARNING] Sol_MultigridPressure3DBase::do_fmg - Failed to converge, error after: L2 = %.12f (%fx), Linf = %.12f (%fx)\n", result_l2, orig_l2 / result_l2, result_linf, orig_linf / result_linf); return false; }
// Convert conserved variables to characteristic variables void ConvertQtoW(int ixy, const dTensorBC4* aux, const dTensorBC4& qold, dTensorBC4& dwp, dTensorBC4& dwm, dTensorBC4& w_cent, void (*ProjectLeftEig)(int, const dTensor1&, const dTensor1&, const dTensor2&, dTensor2&)) { const int mx = qold.getsize(1); const int my = qold.getsize(2); const int meqn = qold.getsize(3); const int mbc = qold.getmbc(); const int maux = aux->getsize(3); const int ksize = w_cent.getsize(4); const int space_order = dogParams.get_space_order(); // ---------------------------------------------------------- // Key: storage of characteristic variables // // wx_cent(i,j,me,1) = Lx * q(i,j,me,2) // wx_cent(i,j,me,2) = Lx * q(i,j,me,4) // wx_cent(i,j,me,3) = Lx * q(i,j,me,5) // // dw_right(i,j,me,1) = Lx * (q(i+1,j,me,1)-q(i,j,me,1)) // dw_right(i,j,me,2) = Lx * (q(i+1,j,me,2)-q(i,j,me,2)) // dw_right(i,j,me,3) = Lx * (q(i,j+1,me,2)-q(i,j,me,2)) // // dw_left(i,j,me,1) = Lx * (q(i,j,me,1)-q(i-1,j,me,1)) // dw_left(i,j,me,2) = Lx * (q(i,j,me,2)-q(i-1,j,me,2)) // dw_left(i,j,me,3) = Lx * (q(i,j,me,2)-q(i,j-1,me,2)) // // wy_cent(i,j,me,1) = Ly * q(i,j,me,3) // wy_cent(i,j,me,2) = Ly * q(i,j,me,4) // wy_cent(i,j,me,3) = Ly * q(i,j,me,6) // // dw_up(i,j,me,1) = Ly * (q(i,j+1,me,1)-q(i,j,me,1)) // dw_up(i,j,me,2) = Ly * (q(i+1,j,me,3)-q(i,j,me,3)) // dw_up(i,j,me,3) = Ly * (q(i,j+1,me,3)-q(i,j,me,3)) // // dw_down(i,j,me,1) = Ly * (q(i,j,me,1)-q(i,j-1,me,1)) // dw_down(i,j,me,2) = Ly * (q(i,j,me,3)-q(i-1,j,me,3)) // dw_down(i,j,me,3) = Ly * (q(i,j,me,3)-q(i,j-1,me,3)) // // ---------------------------------------------------------- // // Loop over all interior grid cells // switch( ixy ) { case 1: #pragma omp parallel for for (int i=(3-mbc); i<=(mx+mbc-2); i++) for (int j=(3-mbc); j<=(my+mbc-2); j++) { iTensor1 nx(3); dTensor1 Aux_ave(maux),Q_ave(meqn); dTensor2 Qin(meqn,ksize),Wout(meqn,ksize); // index for x-direction nx.set(1, 2 ); nx.set(2, 4 ); nx.set(3, 5 ); // Store q and aux values in temporary arrays for (int m=1; m<=meqn; m++) { Q_ave.set(m, qold.get(i,j,m,1) ); } for (int m=1; m<=maux; m++) { Aux_ave.set(m, aux->get(i,j,m,1) ); } // ############################################ // X-DIRECTION // ############################################ // -------------------------------------------- // Part I: dw_right = Lx*( q(i+1,j) - q(i,j) ) // -------------------------------------------- switch( space_order ) { case 3: for (int m=1; m<=meqn; m++) { Qin.set(m,1, qold.get(i+1,j,m,1) - qold.get(i,j,m,1) ); Qin.set(m,2, qold.get(i+1,j,m,2) - qold.get(i,j,m,2) ); Qin.set(m,3, qold.get(i,j+1,m,2) - qold.get(i,j,m,2) ); } break; case 2: for (int m=1; m<=meqn; m++) { Qin.set(m,1, qold.get(i+1,j,m,1) - qold.get(i,j,m,1) ); } break; } // Project Qin onto left eigenvectors in cell (i,j) ProjectLeftEig(1,Aux_ave,Q_ave,Qin,Wout); // Store results in dw_right for (int m=1; m<=meqn; m++) for (int k=1; k<=ksize; k++) { dwp.set(i,j,m,k, Wout.get(m,k) ); } // -------------------------------------------- // -------------------------------------------- // Part II: dw_left = Lx*( q(i,j) - q(i-1,j) ) // -------------------------------------------- switch( space_order ) { case 3: for (int m=1; m<=meqn; m++) { Qin.set(m,1, qold.get(i,j,m,1) - qold.get(i-1,j,m,1) ); Qin.set(m,2, qold.get(i,j,m,2) - qold.get(i-1,j,m,2) ); Qin.set(m,3, qold.get(i,j,m,2) - qold.get(i,j-1,m,2) ); } break; case 2: for (int m=1; m<=meqn; m++) { Qin.set(m,1, qold.get(i,j,m,1) - qold.get(i-1,j,m,1) ); } break; } // Project Qin onto left eigenvectors in cell (i,j) ProjectLeftEig(1,Aux_ave,Q_ave,Qin,Wout); // Store results in dw_left for (int m=1; m<=meqn; m++) for (int k=1; k<=ksize; k++) { dwm.set(i,j,m,k, Wout.get(m,k) ); } // -------------------------------------------- // -------------------------------------------- // Part III: wx_cent = Lx*q(i,j) // -------------------------------------------- for (int m=1; m<=meqn; m++) for (int k=1; k<=ksize; k++) { Qin.set(m,k, qold.get(i,j,m,nx.get(k)) ); } // Project Qin onto left eigenvectors in cell (i,j) ProjectLeftEig(1,Aux_ave,Q_ave,Qin,Wout); // Store results in wx_cent for (int m=1; m<=meqn; m++) for (int k=1; k<=ksize; k++) { w_cent.set(i,j,m,k, Wout.get(m,k) ); } // -------------------------------------------- } break; case 2: #pragma omp parallel for for (int i=(3-mbc); i<=(mx+mbc-2); i++) for (int j=(3-mbc); j<=(my+mbc-2); j++) { iTensor1 ny(3); dTensor1 Aux_ave(maux),Q_ave(meqn); dTensor2 Qin(meqn,ksize),Wout(meqn,ksize); // index for y-direction ny.set(1, 3 ); ny.set(2, 4 ); ny.set(3, 6 ); // Store q and aux values in temporary arrays for (int m=1; m<=meqn; m++) { Q_ave.set(m, qold.get(i,j,m,1) ); } for (int m=1; m<=maux; m++) { Aux_ave.set(m, aux->get(i,j,m,1) ); } // ############################################ // Y-DIRECTION // ############################################ // -------------------------------------------- // Part I: dw_up = Ly*( q(i,j+1) - q(i,j) ) // -------------------------------------------- switch( space_order ) { case 3: for (int m=1; m<=meqn; m++) { Qin.set(m,1, qold.get(i,j+1,m,1) - qold.get(i,j,m,1) ); Qin.set(m,2, qold.get(i+1,j,m,3) - qold.get(i,j,m,3) ); Qin.set(m,3, qold.get(i,j+1,m,3) - qold.get(i,j,m,3) ); } break; case 2: for (int m=1; m<=meqn; m++) { Qin.set(m,1, qold.get(i,j+1,m,1) - qold.get(i,j,m,1) ); } break; } // Project Qin onto left eigenvectors in cell (i,j) ProjectLeftEig(2,Aux_ave,Q_ave,Qin,Wout); // Store results in dw_up for (int m=1; m<=meqn; m++) for (int k=1; k<=ksize; k++) { dwp.set(i,j,m,k, Wout.get(m,k) ); } // -------------------------------------------- // -------------------------------------------- // Part II: dw_down = Ly*( q(i,j) - q(i,j-1) ) // -------------------------------------------- switch( space_order ) { case 3: for (int m=1; m<=meqn; m++) { Qin.set(m,1, qold.get(i,j,m,1) - qold.get(i,j-1,m,1) ); Qin.set(m,2, qold.get(i,j,m,3) - qold.get(i-1,j,m,3) ); Qin.set(m,3, qold.get(i,j,m,3) - qold.get(i,j-1,m,3) ); } break; case 2: for (int m=1; m<=meqn; m++) { Qin.set(m,1, qold.get(i,j,m,1) - qold.get(i,j-1,m,1) ); } break; } // Project Qin onto left eigenvectors in cell (i,j) ProjectLeftEig(2,Aux_ave,Q_ave,Qin,Wout); // Store results in dw_down for (int m=1; m<=meqn; m++) for (int k=1; k<=ksize; k++) { dwm.set(i,j,m,k, Wout.get(m,k) ); } // -------------------------------------------- // -------------------------------------------- // Part III: wy_cent = Ly*q(i,j) // -------------------------------------------- for (int m=1; m<=meqn; m++) for (int k=1; k<=ksize; k++) { Qin.set(m,k, qold.get(i,j,m,ny.get(k)) ); } // Project Qin onto left eigenvectors in cell (i,j) ProjectLeftEig(2,Aux_ave,Q_ave,Qin,Wout); // Store results in wy_cent for (int m=1; m<=meqn; m++) for (int k=1; k<=ksize; k++) { w_cent.set(i,j,m,k, Wout.get(m,k) ); } // -------------------------------------------- } break; } }
//--------------------------------------------------------- void NDG3D::PoissonIPDG3D(CSd& spOP, CSd& spMM) //--------------------------------------------------------- { // function [OP,MM] = PoissonIPDG3D() // // Purpose: Set up the discrete Poisson matrix directly // using LDG. The operator is set up in the weak form DVec faceR("faceR"), faceS("faceS"), faceT("faceT"); DMat V2D; IVec Fm("Fm"); IVec i1_Nfp = Range(1,Nfp); double opti1=0.0, opti2=0.0; int i=0; umLOG(1, "\n ==> {OP,MM} assembly: "); opti1 = timer.read(); // time assembly // build local face matrices DMat massEdge[5]; // = zeros(Np,Np,Nfaces); for (i=1; i<=Nfaces; ++i) { massEdge[i].resize(Np,Np); } // face mass matrix 1 Fm = Fmask(All,1); faceR=r(Fm); faceS=s(Fm); V2D = Vandermonde2D(N, faceR, faceS); massEdge[1](Fm,Fm) = inv(V2D*trans(V2D)); // face mass matrix 2 Fm = Fmask(All,2); faceR = r(Fm); faceT = t(Fm); V2D = Vandermonde2D(N, faceR, faceT); massEdge[2](Fm,Fm) = inv(V2D*trans(V2D)); // face mass matrix 3 Fm = Fmask(All,3); faceS = s(Fm); faceT = t(Fm); V2D = Vandermonde2D(N, faceS, faceT); massEdge[3](Fm,Fm) = inv(V2D*trans(V2D)); // face mass matrix 4 Fm = Fmask(All,4); faceS = s(Fm); faceT = t(Fm); V2D = Vandermonde2D(N, faceS, faceT); massEdge[4](Fm,Fm) = inv(V2D*trans(V2D)); // build local volume mass matrix MassMatrix = trans(invV)*invV; DMat Dx("Dx"),Dy("Dy"),Dz("Dz"), Dx2("Dx2"),Dy2("Dy2"),Dz2("Dz2"); DMat Dn1("Dn1"),Dn2("Dn2"), mmE("mmE"), OP11("OP11"), OP12("OP12"); DMat mmE_All_Fm1, mmE_Fm1_Fm1, Dn2_Fm2_All; IMat rows1,cols1,rows2,cols2; int k1=0,f1=0,k2=0,f2=0,id=0; Index1D entries, entriesMM, idsM; IVec fidM,vidM,Fm1,vidP,Fm2; double lnx=0.0,lny=0.0,lnz=0.0,lsJ=0.0,hinv=0.0,gtau=0.0; double N1N1 = double((N+1)*(N+1)); int NpNp = Np*Np; // build DG derivative matrices int max_OP = (K*Np*Np*(1+Nfaces)); int max_MM = (K*Np*Np); // "OP" triplets (i,j,x), extracted to {Ai,Aj,Ax} IVec OPi(max_OP), OPj(max_OP), Ai,Aj; DVec OPx(max_OP), Ax; // "MM" triplets (i,j,x) IVec MMi(max_MM), MMj(max_MM); DVec MMx(max_MM); IVec OnesNp = Ones(Np); // global node numbering entries.reset(1,NpNp); entriesMM.reset(1,NpNp); OP12.resize(Np,Np); for (k1=1; k1<=K; ++k1) { if (! (k1%250)) { umLOG(1, "%d, ",k1); } rows1 = outer( Range((k1-1)*Np+1,k1*Np), OnesNp ); cols1 = trans(rows1); // Build local operators Dx = rx(1,k1)*Dr + sx(1,k1)*Ds + tx(1,k1)*Dt; Dy = ry(1,k1)*Dr + sy(1,k1)*Ds + ty(1,k1)*Dt; Dz = rz(1,k1)*Dr + sz(1,k1)*Ds + tz(1,k1)*Dt; OP11 = J(1,k1)*(trans(Dx)*MassMatrix*Dx + trans(Dy)*MassMatrix*Dy + trans(Dz)*MassMatrix*Dz); // Build element-to-element parts of operator for (f1=1; f1<=Nfaces; ++f1) { k2 = EToE(k1,f1); f2 = EToF(k1,f1); rows2 = outer( Range((k2-1)*Np+1, k2*Np), OnesNp ); cols2 = trans(rows2); fidM = (k1-1)*Nfp*Nfaces + (f1-1)*Nfp + i1_Nfp; vidM = vmapM(fidM); Fm1 = mod(vidM-1,Np)+1; vidP = vmapP(fidM); Fm2 = mod(vidP-1,Np)+1; id = 1+(f1-1)*Nfp + (k1-1)*Nfp*Nfaces; lnx = nx(id); lny = ny(id); lnz = nz(id); lsJ = sJ(id); hinv = std::max(Fscale(id), Fscale(1+(f2-1)*Nfp, k2)); Dx2 = rx(1,k2)*Dr + sx(1,k2)*Ds + tx(1,k2)*Dt; Dy2 = ry(1,k2)*Dr + sy(1,k2)*Ds + ty(1,k2)*Dt; Dz2 = rz(1,k2)*Dr + sz(1,k2)*Ds + tz(1,k2)*Dt; Dn1 = lnx*Dx + lny*Dy + lnz*Dz; Dn2 = lnx*Dx2 + lny*Dy2 + lnz*Dz2; mmE = lsJ*massEdge[f1]; gtau = 2.0 * N1N1 * hinv; // set penalty scaling if (EToE(k1,f1)==k1) { OP11 += ( gtau*mmE - mmE*Dn1 - trans(Dn1)*mmE ); // ok } else { // interior face variational terms OP11 += 0.5*( gtau*mmE - mmE*Dn1 - trans(Dn1)*mmE ); // extract mapped regions: mmE_All_Fm1 = mmE(All,Fm1); mmE_Fm1_Fm1 = mmE(Fm1,Fm1); Dn2_Fm2_All = Dn2(Fm2,All); OP12 = 0.0; // reset to zero OP12(All,Fm2) = -0.5*( gtau*mmE_All_Fm1 ); OP12(Fm1,All) -= 0.5*( mmE_Fm1_Fm1*Dn2_Fm2_All ); //OP12(All,Fm2) -= 0.5*(-trans(Dn1)*mmE_All_Fm1 ); OP12(All,Fm2) += 0.5*( trans(Dn1)*mmE_All_Fm1 ); // load this set of triplets #if (1) OPi(entries)=rows1; OPj(entries)=cols2, OPx(entries)=OP12; entries += (NpNp); #else //########################################################### // load only the lower triangle (after droptol test?) sk=0; start=entries(1); for (int i=1; i<=NpNp; ++i) { eid = start+i; id=entries(eid); rid=rows1(i); cid=cols2(i); if (rows1(rid) >= cid) { // take lower triangle if ( fabs(OP12(id)) > 1e-15) { // drop small entries ++sk; OPi(id)=rid; OPj(id)=cid, OPx(id)=OP12(id); } } } entries += sk; //########################################################### #endif } } OPi(entries )=rows1; OPj(entries )=cols1, OPx(entries )=OP11; MMi(entriesMM)=rows1; MMj(entriesMM)=cols1; MMx(entriesMM)=J(1,k1)*MassMatrix; entries += (NpNp); entriesMM += (NpNp); } umLOG(1, "\n ==> {OP,MM} to sparse\n"); entries.reset(1, entries.hi()-Np*Np); // Extract triplets from the large buffers. Note: this // requires copying each array, and since these arrays // can be HUGE(!), we force immediate deallocation: Ai=OPi(entries); OPi.Free(); Aj=OPj(entries); OPj.Free(); Ax=OPx(entries); OPx.Free(); umLOG(1, " ==> triplets ready (OP) nnz = %10d\n", entries.hi()); // adjust triplet indices for 0-based sparse operators Ai -= 1; Aj -= 1; MMi -= 1; MMj -= 1; int npk=Np*K; #if defined(NDG_USE_CHOLMOD) || defined(NDG_New_CHOLINC) // load only the lower triangle tril(OP) free args? spOP.load(npk,npk, Ai,Aj,Ax, sp_LT, false,1e-15, true); // {LT, false} -> TriL #else // select {upper,lower,both} triangles //spOP.load(npk,npk, Ai,Aj,Ax, sp_LT, true,1e-15,true); // LT -> enforce symmetry //spOP.load(npk,npk, Ai,Aj,Ax, sp_All,true,1e-15,true); // All-> includes "noise" //spOP.load(npk,npk, Ai,Aj,Ax, sp_UT, false,1e-15,true); // UT -> triu(OP) only #endif Ai.Free(); Aj.Free(); Ax.Free(); umLOG(1, " ==> triplets ready (MM) nnz = %10d\n", entriesMM.hi()); //------------------------------------------------------- // The mass matrix operator will NOT be factorised, // Load ALL elements (both upper and lower triangles): //------------------------------------------------------- spMM.load(npk,npk, MMi,MMj,MMx, sp_All,false,1.00e-15,true); MMi.Free(); MMj.Free(); MMx.Free(); opti2 = timer.read(); // time assembly umLOG(1, " ==> {OP,MM} converted to csc. (%g secs)\n", opti2-opti1); }
void Board::release_miai(Move mv) { // WARNING: does not alter miai connectivity int y = reply[nx(mv.s)][mv.lcn]; reply[nx(mv.s)][mv.lcn] = mv.lcn; reply[nx(mv.s)][y] = y; }
/******************************************************************* * * NAME : update_matrix() * * * DESCRIPTION : Updates the Slater matrix with the * coordinates of the active particle. * */ void Slater::update_matrix() { if (active_particle < N) { for (int i = 0; i < N; i++) { Dp_new(i, active_particle) = orbital->evaluate(r_new.row(active_particle), nx(i), ny(i)); } } else { for (int i = 0; i < N; i++) { Dm_new(i, active_particle - N) = orbital->evaluate(r_new.row(active_particle), nx(i), ny(i)); } } }
int Board::moveMiaiPart(Move mv, bool useMiai, int& bdset, int cpt) { // useMiai true... continue with move( )... int nbr,nbrRoot; int lcn = mv.lcn; int s = mv.s; release_miai(mv); // your own miai, so connectivity ok int miReply = reply[nx(opt(s))][lcn]; if (miReply != lcn) { // playing into opponent miai... which will be released // WARNING: if opp'ts next move is not to the miai response, conn'ty needs to be recomputed //prtLcn(lcn); printf(" released opponent miai\n"); release_miai(Move(opt(s),lcn)); } // avoid directional bridge bias: search in random order int x, perm[NumNbrs] = {0, 1, 2, 3, 4, 5}; shuffle_interval(perm,0,NumNbrs-1); for (int t=0; t<NumNbrs; t++) { // look for miai nbrs // in this order 1) connecting to a stone 2) connecting to a side x = perm[t]; assert((x>=0)&&(x<NumNbrs)); nbr = lcn + Bridge_offsets[x]; // nbr via bridge int c1 = lcn+Nbr_offsets[x]; // miai carrier int c2 = lcn+Nbr_offsets[x+1]; // other miai carrier Move mv1(s,c1); Move mv2(s,c2); // y border realign: move the miai so stones are connected *and* adjacent to border // * - becomes * m // m m * - m * // g g g g g g g g <- border guards // rearrange this: 4 cases: both before/after miais possible, only after, only before, none of above if (board[nbr] == s && board[c1] == EMP && board[c2] == EMP && (not_in_miai(mv1)||not_in_miai(mv2))) { if (!not_in_miai(mv1)) { if (near_edge(c1) && (near_edge(lcn) || near_edge(nbr))) YborderRealign(Move(s,nbr),cpt,c1,reply[nx(s)][c1],c2); } else if (!not_in_miai(mv2)) { if (near_edge(c2) && (near_edge(lcn) || near_edge(nbr))) YborderRealign(Move(s,nbr),cpt,c2,reply[nx(s)][c2],c1); } else if (Find(p,nbr)!=Find(p,cpt)) { // new miai candidate //nbrRoot = Find(p,nbr); //int b = brdr[nbrRoot] | brdr[cpt]; //int nbr0 = lcn+Bridge_offsets[x-1]; int c0 = lcn + Nbr_offsets[x-1]; //if ((board[nbr0]==s) && (board[c0]==EMP) && (Find(p,nbr0)!=Find(p,cpt))) { //// nbr0 also new miai candidate, which is better? //int nbrRoot0 = Find(p,nbr0); //int b0 = brdr[nbrRoot0] | brdr[cpt]; //if (numSetBits(b0) > numSetBits(b)) { c2 = c0; nbrRoot = nbrRoot0; } //} //int nbr2 = lcn+Bridge_offsets[x+1]; int c3 = lcn + Nbr_offsets[x+2]; //if ((board[nbr2]==s) && (board[c3]==EMP) && (Find(p,nbr2)!=Find(p,cpt))) { //int nbrRoot2 = Find(p,nbr2); //int b2 = brdr[nbrRoot2] | brdr[cpt]; //int b = brdr[nbrRoot] | brdr[cpt]; //if (numSetBits(b2) > numSetBits(b)) { c1 = c3; nbrRoot = nbrRoot2; } nbrRoot = Find(p,nbr); //int b = brdr[nbrRoot] | brdr[cpt]; brdr[nbrRoot] |= brdr[cpt]; cpt = Union(p,cpt,nbrRoot); set_miai(s,c1,c2); } } else if ((board[nbr] == GRD) && (board[c1] == EMP) && (board[c2] == EMP) && (not_in_miai(mv1))&& (not_in_miai(mv2))) { // new miai brdr[cpt] |= brdr[nbr]; set_miai(s,c1,c2); } } bdset = brdr[cpt]; return miReply; }
void NDG2D::PoissonIPDGbc2D( CSd& spOP //[out] sparse operator ) { // function [OP] = PoissonIPDGbc2D() // Purpose: Set up the discrete Poisson matrix directly // using LDG. The operator is set up in the weak form // build DG derivative matrices int max_OP = (K*Np*Np*(1+Nfaces)); //initialize parameters DVec faceR("faceR"), faceS("faceS"); IVec Fm("Fm"), Fm1("Fm1"), fidM("fidM"); DMat V1D("V1D"); int i=0; // build local face matrices DMat massEdge[4]; // = zeros(Np,Np,Nfaces); for (i=1; i<=Nfaces; ++i) { massEdge[i].resize(Np,Np); } // face mass matrix 1 Fm = Fmask(All,1); faceR = r(Fm); V1D = Vandermonde1D(N, faceR); massEdge[1](Fm,Fm) = inv(V1D*trans(V1D)); // face mass matrix 2 Fm = Fmask(All,2); faceR = r(Fm); V1D = Vandermonde1D(N, faceR); massEdge[2](Fm,Fm) = inv(V1D*trans(V1D)); // face mass matrix 3 Fm = Fmask(All,3); faceS = s(Fm); V1D = Vandermonde1D(N, faceS); massEdge[3](Fm,Fm) = inv(V1D*trans(V1D)); //continue initialize parameters DMat Dx("Dx"),Dy("Dy"), Dn1("Dn1"), mmE_Fm1("mmE(:,Fm1)"); double lnx=0.0,lny=0.0,lsJ=0.0,hinv=0.0,gtau=0.0; int k1=0,f1=0,id=0; IVec i1_Nfp = Range(1,Nfp); double N1N1 = double((N+1)*(N+1)); // "OP" triplets (i,j,x), extracted to {Ai,Aj,Ax} IVec OPi(max_OP),OPj(max_OP), Ai,Aj; DVec OPx(max_OP), Ax; IMat rows1, cols1; Index1D entries; DMat OP11(Np,Nfp, 0.0); // global node numbering entries.reset(1,Np*Nfp); cols1 = outer(Ones(Np), Range(1,Nfp)); umMSG(1, "\n ==> {OP} assembly [bc]: "); for (k1=1; k1<=K; ++k1) { if (! (k1%100)) { umMSG(1, "%d, ",k1); } rows1 = outer(Range((k1-1)*Np+1,k1*Np), Ones(Nfp)); // Build element-to-element parts of operator for (f1=1; f1<=Nfaces; ++f1) { if (BCType(k1,f1)) { ////////////////////////added by Kevin /////////////////////////////// Fm1 = Fmask(All,f1); fidM = (k1-1)*Nfp*Nfaces + (f1-1)*Nfp + i1_Nfp; id = 1+(f1-1)*Nfp + (k1-1)*Nfp*Nfaces; lnx = nx(id); lny = ny(id); lsJ = sJ(id); hinv = Fscale(id); Dx = rx(1,k1)*Dr + sx(1,k1)*Ds; Dy = ry(1,k1)*Dr + sy(1,k1)*Ds; Dn1 = lnx*Dx + lny*Dy; //mmE = lsJ*massEdge(:,:,f1); //bc(All,k1) += (gtau*mmE(All,Fm1) - Dn1'*mmE(All,Fm1))*ubc(fidM); mmE_Fm1 = massEdge[f1](All,Fm1); mmE_Fm1 *= lsJ; gtau = 10*N1N1*hinv; // set penalty scaling //bc(All,k1) += (gtau*mmE_Fm1 - trans(Dn1)*mmE_Fm1) * ubc(fidM); switch(BCType(k1,f1)){ case BC_Dirichlet: OP11 = gtau*mmE_Fm1 - trans(Dn1)*mmE_Fm1; break; case BC_Neuman: OP11 = mmE_Fm1; break; default: std::cout<<"warning: boundary condition is incorrect"<<std::endl; } OPi(entries)=rows1; OPj(entries)=cols1; OPx(entries)=OP11; entries += (Np*Nfp); } cols1 += Nfp; } } umMSG(1, "\n ==> {OPbc} to sparse\n"); entries.reset(1, entries.hi()-(Np*Nfp)); // extract triplets from large buffers Ai=OPi(entries); Aj=OPj(entries); Ax=OPx(entries); // These arrays can be HUGE, so force deallocation OPi.Free(); OPj.Free(); OPx.Free(); // return 0-based sparse result Ai -= 1; Aj -= 1; //------------------------------------------------------- // This operator is not symmetric, and will NOT be // factorised, only used to create reference RHS's: // // refrhsbcPR = spOP1 * bcPR; // refrhsbcUx = spOP2 * bcUx; // refrhsbcUy = spOP2 * bcUy; // // Load ALL elements (both upper and lower triangles): //------------------------------------------------------- spOP.load(Np*K, Nfp*Nfaces*K, Ai,Aj,Ax, sp_All,false, 1e-15,true); Ai.Free(); Aj.Free(); Ax.Free(); umMSG(1, " ==> {OPbc} ready.\n"); #if (1) // check on original estimates for nnx umMSG(1, " ==> max_OP: %12d\n", max_OP); umMSG(1, " ==> nnz_OP: %12d\n", entries.hi()); #endif }
//--------------------------------------------------------- DVec& NDG2D::PoissonIPDGbc2D (DVec& ubc, //[in] DVec& qbc //[in] ) //--------------------------------------------------------- { // function [OP] = PoissonIPDGbc2D() // Purpose: Set up the discrete Poisson matrix directly // using LDG. The operator is set up in the weak form // build DG derivative matrices int max_OP = (K*Np*Np*(1+Nfaces)); // initialize parameters DVec faceR("faceR"), faceS("faceS"); DMat V1D("V1D"), Dx("Dx"),Dy("Dy"), Dn1("Dn1"), mmE_Fm1("mmE(:,Fm1)"); IVec Fm("Fm"), Fm1("Fm1"), fidM("fidM"); double lnx=0.0,lny=0.0,lsJ=0.0,hinv=0.0,gtau=0.0; int i=0,k1=0,f1=0,id=0; IVec i1_Nfp = Range(1,Nfp); double N1N1 = double((N+1)*(N+1)); // build local face matrices DMat massEdge[4]; // = zeros(Np,Np,Nfaces); for (i=1; i<=Nfaces; ++i) { massEdge[i].resize(Np,Np); } // face mass matrix 1 Fm = Fmask(All,1); faceR = r(Fm); V1D = Vandermonde1D(N, faceR); massEdge[1](Fm,Fm) = inv(V1D*trans(V1D)); // face mass matrix 2 Fm = Fmask(All,2); faceR = r(Fm); V1D = Vandermonde1D(N, faceR); massEdge[2](Fm,Fm) = inv(V1D*trans(V1D)); // face mass matrix 3 Fm = Fmask(All,3); faceS = s(Fm); V1D = Vandermonde1D(N, faceS); massEdge[3](Fm,Fm) = inv(V1D*trans(V1D)); // build DG right hand side DVec* pBC = new DVec(Np*K, "bc", OBJ_temp); DVec& bc = (*pBC); // reference, for syntax //////////////////////////////////////////////////////////////// umMSG(1, "\n ==> {OP} assembly [bc]: "); for (k1=1; k1<=K; ++k1) { if (! (k1%100)) { umMSG(1, "%d, ",k1); } // rows1 = outer(Range((k1-1)*Np+1,k1*Np), Ones(NGauss)); // Build element-to-element parts of operator for (f1=1; f1<=Nfaces; ++f1) { if (BCType(k1,f1)) { ////////////////////////added by Kevin /////////////////////////////// Fm1 = Fmask(All,f1); fidM = (k1-1)*Nfp*Nfaces + (f1-1)*Nfp + i1_Nfp; id = 1+(f1-1)*Nfp + (k1-1)*Nfp*Nfaces; lnx = nx(id); lny = ny(id); lsJ = sJ(id); hinv = Fscale(id); Dx = rx(1,k1)*Dr + sx(1,k1)*Ds; Dy = ry(1,k1)*Dr + sy(1,k1)*Ds; Dn1 = lnx*Dx + lny*Dy; //mmE = lsJ*massEdge(:,:,f1); //bc(All,k1) += (gtau*mmE(All,Fm1) - Dn1'*mmE(All,Fm1))*ubc(fidM); mmE_Fm1 = massEdge[f1](All,Fm1); mmE_Fm1 *= lsJ; gtau = 10*N1N1*hinv; // set penalty scaling //bc(All,k1) += (gtau*mmE_Fm1 - trans(Dn1)*mmE_Fm1) * ubc(fidM); switch(BCType(k1,f1)){ case BC_Dirichlet: bc(Np*(k1-1)+Range(1,Np)) += (gtau*mmE_Fm1 - trans(Dn1)*mmE_Fm1)*ubc(fidM); break; case BC_Neuman: bc(Np*(k1-1)+Range(1,Np)) += mmE_Fm1*qbc(fidM); break; default: std::cout<<"warning: boundary condition is incorrect"<<std::endl; } } } } return bc; }
osg::Node* createCube(unsigned int mask) { osg::Geode* geode = new osg::Geode; osg::Geometry* geometry = new osg::Geometry; geode->addDrawable(geometry); osg::Vec3Array* vertices = new osg::Vec3Array; geometry->setVertexArray(vertices); osg::Vec3Array* normals = new osg::Vec3Array; geometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX); osg::Vec4Array* colours = new osg::Vec4Array; geometry->setColorArray(colours, osg::Array::BIND_OVERALL); colours->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); osg::Vec3 origin(0.0f,0.0f,0.0f); osg::Vec3 dx(2.0f,0.0f,0.0f); osg::Vec3 dy(0.0f,1.0f,0.0f); osg::Vec3 dz(0.0f,0.0f,1.0f); osg::Vec3 px(1.0f,0.0,0.0f); osg::Vec3 nx(-1.0f,0.0,0.0f); osg::Vec3 py(0.0f,1.0f,0.0f); osg::Vec3 ny(0.0f,-1.0f,0.0f); osg::Vec3 pz(0.0f,0.0f,1.0f); osg::Vec3 nz(0.0f,0.0f,-1.0f); if (mask & FRONT_FACE) { // front face vertices->push_back(origin); vertices->push_back(origin+dx); vertices->push_back(origin+dx+dz); vertices->push_back(origin+dz); normals->push_back(ny); normals->push_back(ny); normals->push_back(ny); normals->push_back(ny); } if (mask & BACK_FACE) { // back face vertices->push_back(origin+dy); vertices->push_back(origin+dy+dz); vertices->push_back(origin+dy+dx+dz); vertices->push_back(origin+dy+dx); normals->push_back(py); normals->push_back(py); normals->push_back(py); normals->push_back(py); } if (mask & LEFT_FACE) { // left face vertices->push_back(origin+dy); vertices->push_back(origin); vertices->push_back(origin+dz); vertices->push_back(origin+dy+dz); normals->push_back(nx); normals->push_back(nx); normals->push_back(nx); normals->push_back(nx); } if (mask & RIGHT_FACE) { // right face vertices->push_back(origin+dx+dy); vertices->push_back(origin+dx+dy+dz); vertices->push_back(origin+dx+dz); vertices->push_back(origin+dx); normals->push_back(px); normals->push_back(px); normals->push_back(px); normals->push_back(px); } if (mask & TOP_FACE) { // top face vertices->push_back(origin+dz); vertices->push_back(origin+dz+dx); vertices->push_back(origin+dz+dx+dy); vertices->push_back(origin+dz+dy); normals->push_back(pz); normals->push_back(pz); normals->push_back(pz); normals->push_back(pz); } if (mask & BOTTOM_FACE) { // bottom face vertices->push_back(origin); vertices->push_back(origin+dy); vertices->push_back(origin+dx+dy); vertices->push_back(origin+dx); normals->push_back(nz); normals->push_back(nz); normals->push_back(nz); normals->push_back(nz); } geometry->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, vertices->size())); return geode; }
bool ImageBundle::contains(const ImageRef& ir) const { return ir.x >= 0 && ir.y >= 0 && ir.x < nx() && ir.y < ny(); }
//-------------------------------------------------------------------------- //-------- execute --------------------------------------------------------- //-------------------------------------------------------------------------- void AssembleMomentumEdgeOpenSolverAlgorithm::execute() { stk::mesh::BulkData & bulk_data = realm_.bulk_data(); stk::mesh::MetaData & meta_data = realm_.meta_data(); const int nDim = meta_data.spatial_dimension(); // nearest face entrainment const double nfEntrain = realm_.solutionOptions_->nearestFaceEntrain_; const double om_nfEntrain = 1.0-nfEntrain; // space for dui/dxj; the modified gradient with NOC std::vector<double> duidxj(nDim*nDim); // lhs/rhs space std::vector<stk::mesh::Entity> connected_nodes; std::vector<double> rhs; std::vector<double> lhs; std::vector<double> nx(nDim); std::vector<double> fx(nDim); // pointers double *p_duidxj = &duidxj[0]; double *p_nx = &nx[0]; double *p_fx = &fx[0]; // deal with state VectorFieldType &velocityNp1 = velocity_->field_of_state(stk::mesh::StateNP1); // define vector of parent topos std::vector<stk::topology> parentTopo; // define some common selectors stk::mesh::Selector s_locally_owned_union = meta_data.locally_owned_part() &stk::mesh::selectUnion(partVec_); stk::mesh::BucketVector const& face_buckets = realm_.get_buckets( meta_data.side_rank(), s_locally_owned_union ); for ( stk::mesh::BucketVector::const_iterator ib = face_buckets.begin(); ib != face_buckets.end() ; ++ib ) { stk::mesh::Bucket & b = **ib ; // extract connected element topology b.parent_topology(stk::topology::ELEMENT_RANK, parentTopo); ThrowAssert ( parentTopo.size() == 1 ); stk::topology theElemTopo = parentTopo[0]; MasterElement *meSCS = realm_.get_surface_master_element(theElemTopo); const int nodesPerElement = meSCS->nodesPerElement_; // resize some things; matrix related const int lhsSize = nodesPerElement*nDim*nodesPerElement*nDim; const int rhsSize = nodesPerElement*nDim; lhs.resize(lhsSize); rhs.resize(rhsSize); connected_nodes.resize(nodesPerElement); // pointer to lhs/rhs double *p_lhs = &lhs[0]; double *p_rhs = &rhs[0]; // size some things that are useful const int num_face_nodes = b.topology().num_nodes(); std::vector<int> face_node_ordinals(num_face_nodes); const stk::mesh::Bucket::size_type length = b.size(); for ( stk::mesh::Bucket::size_type k = 0 ; k < length ; ++k ) { // zero lhs/rhs for ( int p = 0; p < lhsSize; ++p ) p_lhs[p] = 0.0; for ( int p = 0; p < rhsSize; ++p ) p_rhs[p] = 0.0; // pointer to face data const double * areaVec = stk::mesh::field_data(*exposedAreaVec_, b, k); const double * mdot = stk::mesh::field_data(*openMassFlowRate_, b, k); // extract the connected element to this exposed face; should be single in size! stk::mesh::Entity const * face_elem_rels = b.begin_elements(k); ThrowAssert( b.num_elements(k) == 1 ); // get element; its face ordinal number and populate face_node_ordinals stk::mesh::Entity element = face_elem_rels[0]; const int face_ordinal = b.begin_element_ordinals(k)[0]; theElemTopo.side_node_ordinals(face_ordinal, face_node_ordinals.begin()); // get the relations; populate connected nodes stk::mesh::Entity const * elem_node_rels = bulk_data.begin_nodes(element); int num_nodes = bulk_data.num_nodes(element); // sanity check on num nodes ThrowAssert( num_nodes == nodesPerElement ); for ( int ni = 0; ni < num_nodes; ++ni ) { // set connected nodes connected_nodes[ni] = elem_node_rels[ni]; } // loop over face nodes (maps directly to ips) for ( int ip = 0; ip < num_face_nodes; ++ip ) { const int opposingNode = meSCS->opposingNodes(face_ordinal,ip); // "Left" const int nearestNode = face_node_ordinals[ip]; // "Right" // left and right nodes; right is on the face; left is the opposing node stk::mesh::Entity nodeL = elem_node_rels[opposingNode]; stk::mesh::Entity nodeR = elem_node_rels[nearestNode]; // extract nodal fields const double * coordL = stk::mesh::field_data(*coordinates_, nodeL ); const double * coordR = stk::mesh::field_data(*coordinates_, nodeR ); const double * uNp1L = stk::mesh::field_data(velocityNp1, nodeL ); const double * uNp1R = stk::mesh::field_data(velocityNp1, nodeR ); const double viscosityR = *stk::mesh::field_data(*viscosity_, nodeR ); const double viscBip = viscosityR; // a few only required (or even defined) on nodeR const double *bcVelocity = stk::mesh::field_data(*velocityBc_, nodeR ); const double * dudxR = stk::mesh::field_data(*dudx_, nodeR ); // offset for bip area vector const int faceOffSet = ip*nDim; // compute geometry double axdx = 0.0; double asq = 0.0; double udotx = 0.0; for ( int j = 0; j < nDim; ++j ) { const double axj = areaVec[faceOffSet+j]; const double dxj = coordR[j] - coordL[j]; asq += axj*axj; axdx += axj*dxj; udotx += 0.5*dxj*(uNp1L[j] + uNp1R[j]); } const double inv_axdx = 1.0/axdx; const double amag = std::sqrt(asq); // form duidxj with over-relaxed procedure of Jasak: for ( int i = 0; i < nDim; ++i ) { // difference between R and L nodes for component i const double uidiff = uNp1R[i] - uNp1L[i]; // offset into all forms of dudx const int offSetI = nDim*i; // start sum for NOC contribution double GlUidxl = 0.0; for ( int l = 0; l< nDim; ++l ) { const int offSetIL = offSetI+l; const double dxl = coordR[l] - coordL[l]; const double GlUi = dudxR[offSetIL]; GlUidxl += GlUi*dxl; } // form full tensor dui/dxj with NOC for ( int j = 0; j < nDim; ++j ) { const int offSetIJ = offSetI+j; const double axj = areaVec[faceOffSet+j]; const double GjUi = dudxR[offSetIJ]; p_duidxj[offSetIJ] = GjUi + (uidiff - GlUidxl)*axj*inv_axdx; } } // divU double divU = 0.0; for ( int j = 0; j < nDim; ++j) divU += p_duidxj[j*nDim+j]; double fxnx = 0.0; double uxnx = 0.0; double uxnxip = 0.0; double uspecxnx = 0.0; for (int i = 0; i < nDim; ++i ) { const double axi = areaVec[faceOffSet+i]; double fxi = 2.0/3.0*viscBip*divU*axi*includeDivU_; const int offSetI = nDim*i; const double nxi = axi/amag; for ( int j = 0; j < nDim; ++j ) { const int offSetTrans = nDim*j+i; const double axj = areaVec[faceOffSet+j]; fxi += -viscBip*(p_duidxj[offSetI+j] + p_duidxj[offSetTrans])*axj; } fxnx += nxi*fxi; uxnx += nxi*uNp1R[i]; uxnxip += 0.5*nxi*(uNp1L[i]+uNp1R[i]); uspecxnx += nxi*bcVelocity[i]; // save off normal and force for each component i p_nx[i] = nxi; p_fx[i] = fxi; } // full stress, sigma_ij for (int i = 0; i < nDim; ++i ) { // setup for matrix contribution assembly const int indexL = opposingNode*nDim + i; const int indexR = nearestNode*nDim + i; const int rowR = indexR*nodesPerElement*nDim; const int rRiL_i = rowR+indexL; const int rRiR_i = rowR+indexR; // subtract normal component const double diffFlux = p_fx[i] - p_nx[i]*fxnx; const double om_nxinxi = 1.0-p_nx[i]*p_nx[i]; p_rhs[indexR] -= diffFlux; double lhsFac = -viscBip*asq*inv_axdx*om_nxinxi; p_lhs[rRiL_i] -= lhsFac; p_lhs[rRiR_i] += lhsFac; const double axi = areaVec[faceOffSet+i]; for ( int j = 0; j < nDim; ++j ) { const double axj = areaVec[faceOffSet+j]; lhsFac = -viscBip*axi*axj*inv_axdx*om_nxinxi; const int colL = opposingNode*nDim + j; const int colR = nearestNode*nDim + j; const int rRiL_j = rowR+colL; const int rRiR_j = rowR+colR; p_lhs[rRiL_j] -= lhsFac; p_lhs[rRiR_j] += lhsFac; if ( i == j ) { // nothing } else { const double nxinxj = p_nx[i]*p_nx[j]; lhsFac = viscBip*asq*inv_axdx*nxinxj; p_lhs[rRiL_j] -= lhsFac; p_lhs[rRiR_j] += lhsFac; lhsFac = viscBip*axj*axj*inv_axdx*nxinxj; p_lhs[rRiL_j] -= lhsFac; p_lhs[rRiR_j] += lhsFac; lhsFac = viscBip*axj*axi*inv_axdx*nxinxj; p_lhs[rRiL_i] -= lhsFac; p_lhs[rRiR_i] += lhsFac; } } } // advection const double tmdot = mdot[ip]; if ( tmdot > 0 ) { // leaving the domain for ( int i = 0; i < nDim; ++i ) { // setup for matrix contribution assembly const int indexR = nearestNode*nDim + i; const int rowR = indexR*nodesPerElement*nDim; const int rRiR = rowR+indexR; p_rhs[indexR] -= tmdot*uNp1R[i]; p_lhs[rRiR] += tmdot; } } else { // entraining; constrain to be normal for ( int i = 0; i < nDim; ++i ) { // setup for matrix contribution assembly const int indexR = nearestNode*nDim + i; const int rowR = indexR*nodesPerElement*nDim; // constrain to be normal p_rhs[indexR] -= tmdot*(nfEntrain*uxnx + om_nfEntrain*uxnxip)*p_nx[i]; // user spec entrainment (tangential) p_rhs[indexR] -= tmdot*(bcVelocity[i]-uspecxnx*p_nx[i]); for ( int j = 0; j < nDim; ++j ) { const int colL = opposingNode*nDim + j; const int colR = nearestNode*nDim + j; p_lhs[rowR+colR] += tmdot*(nfEntrain + om_nfEntrain*0.5)*p_nx[i]*p_nx[j]; p_lhs[rowR+colL] += tmdot*om_nfEntrain*0.5*p_nx[i]*p_nx[j]; } } } } apply_coeff(connected_nodes, rhs, lhs, __FILE__); } } }
ScriptLauncher::ScriptLauncher( QString fn, QObject * parent): QObject( parent){ QPixmap *pix; QString name; ip = NULL; fileName = fn; //Load XPM QFile file(fileName); if (!file.open(QIODevice::ReadOnly | QIODevice::Text )) qDebug() << "Error launching script"; QRegExp rx( "<XPM>.+\"(.+)\".+</XPM>" ); QString in = file.readAll(); rx.indexIn(in,0); QString captured = rx.cap( 1 ); captured.replace( QRegExp("\"[^\"&.]+\""), "\n" ); QByteArray ascii = captured.toAscii(); const char *xpmbytes=ascii.data(); char * xpmfinal = new char[captured.length()]; int lines = 1; for (int i=0;i<captured.length();i++){ if (xpmbytes[i]=='\n'){ xpmfinal[i]=0; lines++; } else xpmfinal[i]=xpmbytes[i]; } const char ** xpmptrs = new const char*[lines+1]; xpmptrs[0] = xpmfinal; int j = 1; for (int i=0;i<captured.length();i++){ if (xpmfinal[i]=='\0'){ xpmptrs[j]=xpmfinal + i + 1; j++; } } pix = new QPixmap(xpmptrs); delete[] xpmfinal; delete[] xpmptrs; QRegExp fx( "<FILTER>(.+)</FILTER>" ); if (fx.indexIn(in,0))filter = new QRegExp(fx.cap( 1 )); else filter = new QRegExp("(.+)"); qDebug(qPrintable(fx.cap( 1 ))); QRegExp nx( "<NAME>(.+)</NAME>" ); if (nx.indexIn(in,0))name = nx.cap( 1 ); else name = fn; QString tooltip; QRegExp tx( "<DESCRIPTION>(.+)</DESCRIPTION>" ); if (tx.indexIn(in,0))tooltip = tx.cap( 1 ); a = new QAction( QIcon(*pix),name , parent); a->setStatusTip ( tooltip ); toggle = false; QRegExp px( ".*<TOGGLE/>.*" ); if (px.exactMatch(in)){ toggle=true; qDebug() << "toggle"; a->setCheckable ( true ); QObject::connect( a, SIGNAL(triggered(bool)), this, SLOT(toggled(bool))); }