//Final parser, parses node and get data/fields NODE * PARSER::parseNode(char *instring, NODE * node) { string nextwd; NODETYPE ntype; NODE tempnode; int nodeid, curly = 0; char nextstr[MAXSTRSIZE]; stringcopy( nextwd, instring); nodeid = ntype.findNodeType(nextwd); node = parseProtoNode(instring, node);//Check first for PROTO node if(node != NULL){ return node; // If node is PROTO then return pointer to node } if(!nodeid) return NULL; node = tempnode.createNewNode(nodeid, node); getNextWord(nextstr); if(strcmp("{", nextstr) == 0) //Ensure open curly bracket after node name { curly++; }else{ cout << "Experted open curly bracket at " << nextstr << endl; return NULL; } while(getNextWord(nextstr)){ NODE *tnodeptr; if(int n = node->findFieldName(nextstr)){ //Get field for node node->getField(n , node); } if((tnodeptr = parseNodeString(nextstr, tnodeptr))){ //Parse children node and store in scenegraph if(tnodeptr != NULL){ node->children.push_back(tnodeptr); continue; } } if(strcmp("{", nextstr) == 0){ curly++; continue; } if(strcmp("}", nextstr) == 0){ curly--; if(curly == 0){ break; } } } return node; }
void pushDown() { if (!dx && !da && !db && !dc) return; if (l) l->adjx(dx), l->adjy(da,db,dc); if (r) r->adjx(dx), r->adjy(da,db,dc); dx=da=db=dc=0; }
bool operator()(const NODE& node1, const NODE& node2) const { double distance1 = norm(node1.position() - p_); double distance2 = norm(node2.position() - p_); if (distance1 < distance2) return true; else return false; }
QScriptValue ScriptableSyntaxDefinition::GLUE_(QScriptContext* context, QScriptEngine* engine) { checkNumberOfArguments(context, 2, intMax); NODE node = super(context)->GLUE(); for (int i = 0, n = context->argumentCount(); i < n; ++i) node->appendChild(context->argument(i).toVariant().value<NODE>()); return nodeToScriptValue(engine, node); }
Color operator()(const NODE& node) { int contribs = node.value().num_contribs; double val = node.value().sum; double avg = val/((double) contribs); //std::cout << "Color: " << (avg-min_)/(max_-min_) << std::endl; return Color::make_heat((avg-min_)/(max_-min_)); //return Color::make_heat((avg+20.0)/40.0); }
void LIST :: newNODE(SPHERE* data){ NODE* newNode; newNode = new NODE(data); p = tail->getPre(); p->setNext(newNode); newNode->setNext(tail); newNode->setPre(p); tail->setPre(newNode); }
void runShell(char* command) { NODE* cmd; cmd = findCommand(command); if (cmd) cmd->cmd(); tcputs("$>> ", COLOR_GREEN); waitCmd(); }
bool LIST :: deleteNode(){ NODE* tmp; if(p == head || p == tail) return false; tmp = p; p = p->getPre(); p->setNext(tmp->getNext()); p->getNext()->setPre(p); delete tmp; return true; }
Point operator()(MESH& m, NODE n, double t) { (void) t; Point pressure_force = Point(0.0, 0.0, 0.0); for(auto it=m.adj_triangle_begin(n.uid()); it != m.adj_triangle_end(n.uid()); ++ it) { auto tri = (*it); Point normal = get_normal_surface(tri); double area = tri.area(); pressure_force += normal * area * pressure; } return pressure_force; }
void CreateBlueprintVisitorHelper::createWeightedSet(WS *bp, NODE &n) { Blueprint::UP result(bp); FieldSpecList fields; for (size_t i = 0; i < n.getChildren().size(); ++i) { fields.clear(); fields.add(bp->getNextChildField(_field)); const query::Node &node = *n.getChildren()[i]; uint32_t weight = getWeightFromNode(node).percent(); bp->addTerm(_searchable.createBlueprint(_requestContext, fields, node), weight); } setResult(std::move(result)); }
force_type operator() (NODE n, double t){ Point node_velocity = n.value().velocity; Point node_normal(0.0, 0.0, 0.0); for (auto it = n.triangle_begin(); it != n.triangle_end(); ++it){ auto tri = (*it); // approximate node normal vector by the sum of normal vectors of its neighboring faces node_normal += get_normal_surface(tri); } // calculte wind force force_type force = wind_const * dot(wind_velocity_ - node_velocity, node_normal) * node_normal; (void) t; return force; }
force_type operator()(NODE n, double t) { (void) t; force_type pressure_force = Point(0.0, 0.0, 0.0); for(auto it=n.triangle_begin(); it != n.triangle_end(); ++ it) { auto tri = (*it); Point normal = get_normal_surface(tri); double area = tri.area(); pressure_force += normal * area * pressure; } return pressure_force; }
int main() { freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); scanf("%d%d%d%d",&N,&Q,&A,&B); root=new NODE(1,Q); pair<NODE*,long double> MIN; NODE *p; for (int i=1;i<=N;i++) { if (i>1) if (A<B) { MIN=findMin(root); p=MIN.first; long double &mid=MID[i]; mid=MIN.second; Splay(p); NODE *q0, *q1(p->l), *q2(p->r); if (mid-p->xl>eps) q1=new NODE(p->xl,mid,p->a,p->b,p->c,p->l,0); if (p->xr-mid>eps) q2=new NODE(mid,p->xr,p->a,p->b,p->c,0,p->r); if (q1) q1->adjx(A); if (q2) q2->adjx(B); q0=new NODE(mid+A,mid+B,0,0,p->inter(mid),q1,q2); root=q0; delete p; } else root->adjx(A); double x; scanf("%lf",&x); root->adjy(1,-2*x,x*x); } MIN=findMin(root); p=MIN.first; long double x=MIN.second, y=p->inter(x); for (int i=N;i;i--) { ans[i]=x; if (x>MID[i]+B) x-=B; else if (x<MID[i]+A) x-=A; else x=MID[i]; } for (int i=1;i<N;i++) printf("%.8f ",(double)ans[i]); printf("%.8f\n%.8f\n",(double)ans[N],(double)y); return 0; }
Color operator()(const NODE& node) { if (node.value() == true) return Color(0.5); else return Color(1); }
Point operator()(MESH& m, NODE n, double t) { (void) t; (void) m; Point velocity = n.value().velocity; Point return_force = -velocity/num_nodes; return Point(return_force.x,return_force.y,0); }
// セグメントツリーをたどる T prop(int l, int r, T v, int a, int b, int k=1){ // 今いるノードの値を確定させる propLazy(a, b, k); // たどる NODE nd; // 結果保存用(範囲外の場合は初期値が返る) if( l <= a && b <= r ){ // 完全に範囲内の場合 propLazy(a, b, k, v); return data[k].v; }else if( l < b && a < r ){ // 中途半端に含まれる場合 int m = (a+b) / 2; T vl = prop(l,r,v, a, m, k*2); T vr = prop(l,r,v, m, b, k*2+1); data[k].merge( data[k*2].v, data[k*2+1].v ); nd.merge( vl, vr ); } return nd.v; }
force_type operator()(NODE n, double t) { (void) t; force_type force = force_type(0,0,0); Node node2; double distance; double initial_spring_length; double sprint_const_this_edge; // iterate through each neighboring node and add spring forces for(auto it = n.edge_begin(); it != n.edge_end(); ++it) { node2 = (*it).node2(); sprint_const_this_edge = (*it).value().spring_constant; initial_spring_length = (*it).value().initial_length; distance = norm(n.position()-node2.position()); // Euclidean distance force += (-1)*sprint_const_this_edge*(n.position()-node2.position())*(distance-initial_spring_length)/distance; } return force; }
void TOOL_BASE::deleteTraces( ITEM* aStartItem, bool aWholeTrack ) { NODE *node = m_router->GetWorld()->Branch(); if( !aStartItem ) return; if( !aWholeTrack ) { node->Remove( aStartItem ); } else { TOPOLOGY topo( node ); ITEM_SET path = topo.AssembleTrivialPath( aStartItem ); for( auto ent : path.Items() ) node->Remove( ent.item ); } m_router->CommitRouting( node ); }
Point operator()(const NODE& node) { return node.position(); }
void MODEL::DoDryRewet( PROJECT* project, int* dried, int* wetted ) { DRYREW *dryRew = ®ion->dryRew; region->Connection( 0L ); int del = 0; int wel = 0; if( dryRew->method == 1 ) { // mark nodes and elements to be rewetted ------------------------------------------------------ wel = region->Rewet( dryRew->rewetLimit, dryRew->rewetPasses, project ); // mark dry nodes and elements ----------------------------------------------------------------- del = region->Dry( dryRew->dryLimit, dryRew->countDown ); } else if( dryRew->method == 2 ) { region->DryRewet( dryRew->dryLimit, dryRew->rewetLimit, dryRew->countDown, &del, &wel ); } else if( dryRew->method == 3 ) { region->RewetDry( dryRew->dryLimit, dryRew->rewetLimit, dryRew->countDown, &del, &wel ); } /* // future work ... else if( dryRew->method == 4 ) { // determine dynamic boundary ------------------------------------------------------------------ region.DynamicBound( np, node, *elem, dryRew->dryLimit, project ); } */ ////////////////////////////////////////////////////////////////////////////////////////////////// # ifdef _MPI_ del = project->subdom.Mpi_sum( del ); wel = project->subdom.Mpi_sum( wel ); # endif char text [200]; sprintf( text, "\n (MODEL::DoDryRewet) %d elements have got dry\n", del ); REPORT::rpt.Output( text, 3 ); sprintf( text, "\n (MODEL::DoDryRewet) %d elements have got wet\n", wel ); REPORT::rpt.Output( text, 3 ); int dryRewFlag = del + wel; if( dryRewFlag ) { //////////////////////////////////////////////////////////////////////////////////////////////// // exchange information on dry nodes on interfaces # ifdef _MPI_ if( project->subdom.npr > 1 ) { MPI_Comm_Dry( project, true ); ////////////////////////////////////////////////////////////////////////////////////////////// // reset wetted area, in case of dry nodes that are not dry in adjacent subdomains // added on 20.04.2006, sc if( dryRew->method == 2 || dryRew->method == 3 ) { int wetted = 0; for( int n=0; n<region->Getnp(); n++ ) { NODE* nd = region->Getnode(n); nd->mark = false; double H = nd->v.S - nd->zor; if( H < dryRew->dryLimit ) { SF( nd->flag, NODE::kDry ); } else if( isFS(nd->flag, NODE::kDry) ) { nd->mark = true; CF( nd->flag, NODE::kDry ); wetted++; } CF( nd->flag, NODE::kMarsh ); nd->z = nd->zor; } if( dryRew->method == 2 ) { region->DryRewet( dryRew->dryLimit, dryRew->rewetLimit, dryRew->countDown, &del, &wel ); } else if( dryRew->method == 3 ) { region->RewetDry( dryRew->dryLimit, dryRew->rewetLimit, dryRew->countDown, &del, &wel ); } //////////////////////////////////////////////////////////////////////////////////////////// MPI_Comm_Dry( project, false ); wetted = project->subdom.Mpi_sum( wetted ); sprintf( text, "\n (MODEL::DoDryRewet) %d interface nodes have got wet\n", wetted ); REPORT::rpt.Output( text, 3 ); } } //////////////////////////////////////////////////////////////////////////////////////////////// // reset interface flags: kInface, kInface_DN and kInface_UP; this is // necessary for the correct ordering of equations in EQS::ResetEqOrder() project->subdom.SetInface( region ); # endif // #ifdef _MPI_ //////////////////////////////////////////////////////////////////////////////////////////////// // determine 1D boundary elements and ---------------------------------------------------------- // set up slip velocity boundary conditions Initialize(); SetNormal(); SetRotation(); region->SetSlipFlow(); REPORT::rpt.PrintTime( 3 ); // ================================================================================================ # ifdef kDebug_1 for( int n=0; n<region->Getnp(); n++ ) { NODE* ndbg = region->Getnode(n); switch( ndbg->Getname() ) { case 3654: REPORT::rpt.Message( "\n" ); REPORT::rpt.Message( "### NODE %6d: inface = %d\n", ndbg->Getname(), ndbg->flag&NODE::kInface ); REPORT::rpt.Message( "### : inface_dn = %d\n", ndbg->flag&NODE::kInface_DN ); REPORT::rpt.Message( "### : inface_up = %d\n", ndbg->flag&NODE::kInface_UP ); REPORT::rpt.Message( "\n" ); REPORT::rpt.Message( "### : dry = %d\n", ndbg->flag&NODE::kDry ); REPORT::rpt.Message( "### : marsh = %d\n", ndbg->flag&NODE::kMarsh ); REPORT::rpt.Message( "### : H = %f\n", ndbg->v.S - ndbg->zor ); REPORT::rpt.Message( "\n" ); REPORT::rpt.Message( "### : bound = %d\n", ndbg->flag&NODE::kBound ); REPORT::rpt.Message( "### : inflow = %d\n", ndbg->flag&NODE::kInlet ); REPORT::rpt.Message( "### : outflow = %d\n", ndbg->flag&NODE::kOutlet ); REPORT::rpt.Message( "### : rotat = %d\n", ndbg->flag&NODE::kRotat ); REPORT::rpt.Message( "### : noMoment = %d\n", ndbg->flag&NODE::kNoMoment ); REPORT::rpt.Message( "\n" ); REPORT::rpt.Message( "### : countDown = %d\n", ndbg->countDown ); { SUB* sub = ndbg->sub; while( sub ) { REPORT::rpt.Message( "### SUBDOM %4d: dry = %d\n", sub->no+1, sub->dry ); sub = sub->next; } } break; } } # endif // ================================================================================================ } else { // set up structure for connection of nodes to elements ---------------------------------------- // dry elements are not taken into consideration region->Connection( ELEM::kDry ); } if( dried ) *dried = del; if( wetted ) *wetted = wel; region->firstDryRew = false; }
void PRECO_ILUT::Factor( PROJECT* project, EQS* eqs, CRSMAT* crsm ) { REPORT::rpt.Message( 2, "\n (PRECO_ILUT::Factor) preconditioning: ILUT\n" ); //////////////////////////////////////////////////////////////////////////////////////// // 1. initializations and memory allocation int* width = crsm->m_width; int** index = crsm->m_index; REALPR** A = crsm->m_A; //int* Iw = crsi->m_width; //int** Ii = crsi->m_index; REALPR** ILU = crsi->m_A; int ceq = crsi->m_ceq; int neq = crsm->m_neq; int neq_dn = crsm->m_neq_dn; int neq_up = crsm->m_neq_up; //for( int e=0; e<neq; e++ ) Iw[e] = 1; //crsi->Init(); // allocate dynamic front memory ------------------------------------------------------- int mfw = 4 * ceq; fromat = new FROMAT( mfw, neq ); if( !fromat ) REPORT::rpt.Error( kMemoryFault, "can not allocate memory - PRECO_ILUT::Factor(1)" ); //////////////////////////////////////////////////////////////////////////////////////// // 2. LU factorization // // 2.1 MPI: incomplete LU factorization restricted to interior subdomain nodes # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Factor) starting with 2.1\n" ); # endif int maximumFW = 0; for( int e=0; e<neq_up; e++ ) { if( fabs(A[e][0]) < kMinPivot ) { REPORT::rpt.Error( kParameterFault, "%s - PRECO_ILUT::Factor(2)", "factorization can not be applied to the matrix" ); } // equation "e" is elimination equation ---------------------------------------------- fromat->Insert( e, width, index, A ); if( fromat->m_actFW > maximumFW ) maximumFW = fromat->m_actFW; # ifdef kEqCounter if( ((e+1)%1000) == 0 ) { REPORT::rpt.Screen( 2, "\r (PRECO_ILUT::Factor) %d (maximum FW = %d)", e+1, maximumFW ); } # endif fromat->Eliminate( e ); ILU[e][0] = (REALPR) fromat->m_U[fromat->m_actFW]; // diagonal element //if( fabs(ILU[e][0]) < kZero ) //{ // REPORT::rpt.Error( kParameterFault, "%s - PRECO_ILUT::Factor(2)", // "factorization can not be applied to the matrix" ); //} for( int i=1; i<width[e]; i++ ) { int f = index[e][i]; int j = fromat->m_eql[f].ind; if( f > e ) { ILU[e][i] = (REALPR) fromat->m_U[j]; for( int k=1; k<width[f]; k++ ) { if( index[f][k] == e ) { ILU[f][k] = (REALPR) fromat->m_L[j]; break; } } } } //fromat->Sort(); //Ii[e][0] = e; //ILU[e][0] = (REALPR) fromat->m_eqtr[fromat->m_actFW].U; //EQTREE* eqtr = (EQTREE*) fromat->m_root.First(); //while( eqtr ) //{ // int i; // int f = eqtr->e; // i = Iw[e]; // Ii[e][i] = f; // ILU[e][i] = (REALPR) eqtr->U; // Iw[e]++; // i = Iw[f]; // Ii[f][i] = e; // ILU[f][i] = (REALPR) eqtr->L; // Iw[f]++; // if( Iw[e] >= ceq || Iw[f] >= ceq/2 ) break; // eqtr = (EQTREE*) eqtr->Next(); //} // ... } //////////////////////////////////////////////////////////////////////////////////////// // 2.2 MPI communication: // receive interface equations from subdomains with smaller pid (2 <- 1) // s < pid ==> upstream interface nodes //# ifdef _MPI_DBG // REPORT::rpt.Output( " (PRECO_ILUT::Factor) starting with 2.2\n" ); //# endif # ifdef _MPI_ if( project->subdom.npr > 1 ) { SUBDOM* subdom = &project->subdom; INFACE* inface = subdom->inface; MPI_Status status; int df = eqs->dfcn; for( int s=subdom->npr-1; s>=0; s-- ) { int np = inface[s].np; // number of interface nodes if( np > 0 && s < subdom->pid ) // upstream interface nodes { for( int n=0; n<np; n++ ) { NODE* ndr = inface[s].node[n]; if( !isFS(ndr->flag, NODE::kDry) ) // nothing to do if node is dry... { SUB* subr = ndr->sub; while( subr ) { if( subr->no == s ) break; subr = subr->next; } if( !subr->dry ) // ...or if the node is dry in { // any adjacent subdomain for( int e=0; e<df; e++ ) { int req = eqs->GetEqno( ndr, e ); if( req >= 0 ) { int cnt; MPI_Recv( &cnt, 1, MPI_INT, s, 1, MPI_COMM_WORLD, &status ); if( cnt ) { MPI_Recv( inface[s].ria1, cnt, MPI_CHAR, s, 2, MPI_COMM_WORLD, &status ); MPI_Recv( inface[s].ria2, cnt, MPI_INT, s, 3, MPI_COMM_WORLD, &status ); MPI_Recv( inface[s].recv, cnt, MPI_DOUBLE, s, 4, MPI_COMM_WORLD, &status ); for( int j=0; j<cnt; j++ ) { int eid = inface[s].ria1[j]; int name = inface[s].ria2[j]; NODE* ndc = subdom->node[name - 1]; if( ndc ) { int ceq = eqs->GetEqno( ndc, eid ); for( int c=0; c<width[req]; c++ ) { if( index[req][c] == ceq ) { ILU[req][c] += (REALPR)inface[s].recv[j]; break; } } } } } } } } } } } } } //////////////////////////////////////////////////////////////////////////////////////// // 2.3 MPI: factorization of interface nodes //# ifdef _MPI_DBG // REPORT::rpt.Output( " (PRECO_ILUT::Factor) starting with 2.3\n" ); //# endif for( int e=neq_up; e<neq_dn; e++ ) { if( fabs(ILU[e][0]) < kMinPivot ) { int piv = -1; double max = 0.0; for( int j=1; j<width[e]; j++ ) { int eq = index[e][j]; if( eq > e ) { // find column "e" in equation "eq" -------------------------------------------- for( int k=0; k<width[eq]; k++ ) { if( index[eq][k] == e ) { double p = fabs( ILU[eq][k] ); if( p > max ) { piv = eq; max = p; } } } } } if( piv > 0 ) { for( int j=0; j<width[e]; j++ ) { for( int k=0; k<width[piv]; k++ ) { if( index[e][j] == index[piv][k] ) ILU[e][j] += ILU[piv][k]; } } } else { REPORT::rpt.Error( kParameterFault, "ILU-Factorization cannot be applied to the matrix" ); } } // equation "e" is elimination equation ---------------------------------------------- for( int j=1; j<width[e]; j++ ) { int eq = index[e][j]; if( eq > e )// && eq > neq_dn ) // Note: The elimination of just received upstream { // equations (2.2) was performed in prior subdomain double factor = 0.0; // find column "e" in equation "eq" and compute elimination factor --------------- int k; for( k=0; k<width[eq]; k++ ) { if( index[eq][k] == e ) { factor = -ILU[eq][k] / ILU[e][0]; break; } } // save elimination factor (L-Matrix: index[eq][k] == e < eq) -------------------- ILU[eq][k] = (REALPR)factor; // add elimination equation ILU[i] to ILU[eq] ------------------------------------ for( k=1; k<width[e]; k++ ) { if( index[e][k] >= e ) { for( int l=0; l<width[eq]; l++ ) { if( index[eq][l] == index[e][k] ) { ILU[eq][l] += (REALPR)factor * ILU[e][k]; break; } } } } } } } //////////////////////////////////////////////////////////////////////////////////////// // 2.4 MPI communication: // send to subdomain with larger pid (2 -> 3) // s > pid ==> downstream interface nodes //# ifdef _MPI_DBG // REPORT::rpt.Output( " (PRECO_ILUT::Factor) starting with 2.4\n" ); //# endif if( project->subdom.npr > 1 ) { SUBDOM* subdom = &project->subdom; INFACE* inface = subdom->inface; int df = eqs->dfcn; for( int s=0; s<subdom->npr; s++ ) { int np = inface[s].np; // number of interface nodes if( np > 0 && s > subdom->pid ) // downstream interface nodes { for( int n=0; n<np; n++ ) { NODE* ndr = inface[s].node[n]; if( !isFS(ndr->flag, NODE::kDry) ) // nothing to send if the node is dry... { SUB* subr = ndr->sub; while( subr ) { if( subr->no == s ) break; subr = subr->next; } if( !subr->dry ) // ...or if the node is dry in { // any adjacent subdomain for( int e=0; e<df; e++ ) { int req = eqs->GetEqno( ndr, e ); if( req >= 0 ) { int cnt = 0; for( int c=0; c<width[req]; c++ ) { int ceq = index[req][c]; NODE* ndc = eqs->eqnoNode[ceq]; int eid = eqs->eqid[ceq]; // is ndc a point on interface "s"? SUB* subc = ndc->sub; while( subc ) { if( subc->no == s ) break; subc = subc->next; } if( subc ) { inface[s].sia1[cnt] = eid; inface[s].sia2[cnt] = ndc->Getname(); inface[s].send[cnt] = ILU[req][c]; cnt++; } } MPI_Send( &cnt, 1, MPI_INT, s, 1, MPI_COMM_WORLD ); if( cnt ) { MPI_Send( inface[s].sia1, cnt, MPI_CHAR, s, 2, MPI_COMM_WORLD ); MPI_Send( inface[s].sia2, cnt, MPI_INT, s, 3, MPI_COMM_WORLD ); MPI_Send( inface[s].send, cnt, MPI_DOUBLE, s, 4, MPI_COMM_WORLD ); } } } } } } } } } # endif //////////////////////////////////////////////////////////////////////////////////////// # ifdef kDebug { char filename[80]; if( project->subdom.npr == 1 ) sprintf( filename, "ilu_2.4.dbg" ); else sprintf( filename, "ilu_2.4_%02d.dbg", project->subdom.pid+1 ); eqs->ExportEQS( filename, crsi, project ); } # endif //# ifdef _MPI_DBG // REPORT::rpt.Output( " (PRECO_ILUT::Factor) ILU factorization finished\n" ); //# endif }
void PRECO_ILUT::Solve( PROJECT* project, EQS* eqs, double* B, double* X ) { int neq = crsi->m_neq; int neq_dn = crsi->m_neq_dn; int neq_up = crsi->m_neq_up; int* width = crsi->m_width; int** index = crsi->m_index; REALPR** ILU = crsi->m_A; //////////////////////////////////////////////////////////////////////////////////////// // 1. forward solve: manipulate vector B with lower part of matrix ILU // // 1.1 MPI: forward solve for interior subdomain nodes # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Solve) starting with 1.1\n" ); # endif for( int i=0; i<neq_up; i++ ) { X[i] = B[i]; for( int j=1; j<width[i]; j++ ) { int eq = index[i][j]; if( eq < i ) // L-matrix { X[i] += ILU[i][j] * X[eq]; } } } //////////////////////////////////////////////////////////////////////////////////////// // 1.2 MPI communication: // receive from subdomains with smaller pid (2 <- 1) // s < pid ==> upstream interface nodes # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Solve) starting with 1.2\n" ); # endif # ifdef _MPI_ if( project->subdom.npr > 1 ) { SUBDOM* subdom = &project->subdom; INFACE* inface = subdom->inface; MPI_Status status; int df = eqs->dfcn; for( int s=subdom->npr-1; s>=0; s-- ) { int np = inface[s].np; // number of interface nodes if( np > 0 && s < subdom->pid ) // upstream interface nodes { int cnt = 0; # ifdef _MPI_DBG { char text[200]; sprintf( text, " ### receiving from %d:", s+1 ); REPORT::rpt.Output( text ); } # endif MPI_Recv( &cnt, 1, MPI_INT, s, 1, MPI_COMM_WORLD, &status ); # ifdef _MPI_DBG { char text[200]; sprintf( text, " %d values\n", cnt ); REPORT::rpt.Output( text ); } # endif if( cnt ) { MPI_Recv( inface[s].recv, cnt, MPI_DOUBLE, s, 2, MPI_COMM_WORLD, &status ); cnt = 0; for( int n=0; n<np; n++ ) { NODE* nd = inface[s].node[n]; if( !isFS(nd->flag, NODE::kDry) ) // nothing received if node is dry... { SUB* sub = nd->sub; while( sub ) { if( sub->no == s ) break; sub = sub->next; } if( !sub->dry ) // ...or if the node is dry in { // any adjacent subdomain for( int e=0; e<df; e++ ) { int eqno = eqs->GetEqno( nd, e ); if( eqno >= 0 ) { X[eqno] = inface[s].recv[cnt]; cnt++; } } } } } } } } } //////////////////////////////////////////////////////////////////////////////////////// // 1.3 MPI: forward solve for upstream interface nodes // Note: X[i] is not initialized with B[i] since // this was performed in prior subdomain # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Solve) starting with 1.3\n" ); # endif for( int i=neq_up; i<neq_dn; i++ ) { for( int j=1; j<width[i]; j++ ) { int eq = index[i][j]; if( eq < i ) { X[i] += ILU[i][j] * X[eq]; } } } //////////////////////////////////////////////////////////////////////////////////////// // 1.4 MPI: faktorisation of downstream interface nodes # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Solve) starting with 1.4\n" ); # endif for( int i=neq_dn; i<neq; i++ ) { X[i] = B[i]; for( int j=1; j<width[i]; j++ ) { int eq = index[i][j]; if( eq < neq_dn ) { X[i] += ILU[i][j] * X[eq]; } } } //////////////////////////////////////////////////////////////////////////////////////// // 1.5 MPI communication: // send to subdomains with larger pid (2 -> 3) // s > pid ==> downstream interface nodes # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Solve) starting with 1.5\n" ); # endif if( project->subdom.npr > 1 ) { SUBDOM* subdom = &project->subdom; INFACE* inface = subdom->inface; int df = eqs->dfcn; for( int s=0; s<subdom->npr; s++ ) { int np = inface[s].np; // number of interface nodes if( np > 0 && s > subdom->pid ) // downstream interface nodes { int cnt = 0; for( int n=0; n<np; n++ ) { NODE* nd = inface[s].node[n]; if( !isFS(nd->flag, NODE::kDry) ) // nothing to send if the node is dry... { SUB* sub = nd->sub; while( sub ) { if( sub->no == s ) break; sub = sub->next; } if( !sub->dry ) // ...or if the node is dry in { // any adjacent subdomain for( int e=0; e<df; e++ ) { int eqno = eqs->GetEqno( nd, e ); if( eqno >= 0 ) { inface[s].send[cnt] = X[eqno]; cnt++; } } } } } # ifdef _MPI_DBG { char text[200]; sprintf( text, " ### sending %d values to %d\n", cnt, s+1 ); REPORT::rpt.Output( text ); } # endif MPI_Send( &cnt, 1, MPI_INT, s, 1, MPI_COMM_WORLD ); if( cnt ) MPI_Send( inface[s].send, cnt, MPI_DOUBLE, s, 2, MPI_COMM_WORLD ); } } } # endif //////////////////////////////////////////////////////////////////////////////////////// # ifdef kDebug { FILE* dbg; char filename[80]; MODEL* model = project->M2D; GRID* region = model->region; if( project->subdom.npr == 1 ) sprintf( filename, "forwX.dbg" ); else sprintf( filename, "forwX_%02d.dbg", project->subdom.pid ); dbg = fopen( filename, "w" ); fprintf( dbg, "%d\n", region->Getnp() ); for( int n=0; n<region->Getnp(); n++ ) { NODE* nd = region->Getnode( n ); for( int e=0; e<eqs->dfcn; e++ ) { int eqno = eqs->GetEqno( nd, e ); fprintf( dbg, "%5d %1d ", nd->Getname(), e ); if( eqno >= 0 ) fprintf( dbg, "%14.6le\n", X[eqno] ); else fprintf( dbg, "%14.6le\n", 0.0 ); } } fclose( dbg ); } # endif # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Solve) forward solve finished\n" ); # endif //////////////////////////////////////////////////////////////////////////////////////// // 2. solve for X with upper part of matrix ILU (backward substitution) // // 2.1 MPI communication: // receive from subdomains with larger pid (2 <- 3) // s > pid ==> downstream interface nodes # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Solve) starting with 2.1\n" ); # endif # ifdef _MPI_ if( project->subdom.npr > 1 ) { SUBDOM* subdom = &project->subdom; INFACE* inface = subdom->inface; MPI_Status status; int df = eqs->dfcn; for( int s=subdom->npr-1; s>=0; s-- ) { int np = inface[s].np; // number of interface nodes if( np > 0 && s > subdom->pid ) // downstream interface nodes { int cnt = 0; # ifdef _MPI_DBG { char text[200]; sprintf( text, " ### receiving from %d:", s+1 ); REPORT::rpt.Output( text ); } # endif MPI_Recv( &cnt, 1, MPI_INT, s, 1, MPI_COMM_WORLD, &status ); # ifdef _MPI_DBG { char text[200]; sprintf( text, " %d values\n", cnt ); REPORT::rpt.Output( text ); } # endif if( cnt ) { MPI_Recv( inface[s].recv, cnt, MPI_DOUBLE, s, 2, MPI_COMM_WORLD, &status ); cnt = 0; for( int n=0; n<np; n++ ) { NODE* nd = inface[s].node[n]; if( !isFS(nd->flag, NODE::kDry) ) // nothing received if node is dry... { SUB* sub = nd->sub; while( sub ) { if( sub->no == s ) break; sub = sub->next; } if( !sub->dry ) // ...or if the node is dry in { // any adjacent subdomain for( int e=0; e<df; e++ ) { int req = eqs->GetEqno( nd, e ); if( req >= 0 ) { X[req] = inface[s].recv[cnt]; cnt++; } } } } } } } } } //////////////////////////////////////////////////////////////////////////////////////// // 2.2 MPI: solve for upstream interface nodes # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Solve) starting with 2.2\n" ); # endif for( int i=neq_dn-1; i>=neq_up; i-- ) { for( int j=1; j<width[i]; j++ ) { int eq = index[i][j]; if( eq > i ) { X[i] -= ILU[i][j] * X[eq]; } } if( fabs(ILU[i][0]) < kZero ) REPORT::rpt.Error( kParameterFault, "division by zero - EQS::ILU_solver(1)" ); X[i] /= ILU[i][0]; } //////////////////////////////////////////////////////////////////////////////////////// // 2.3 MPI communication: // send to subdomains with smaller pid (2 -> 1) // s < pid ==> upstream interface nodes # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Solve) starting with 2.3\n" ); # endif if( project->subdom.npr > 1 ) { SUBDOM* subdom = &project->subdom; INFACE* inface = subdom->inface; int df = eqs->dfcn; for( int s=0; s<subdom->npr; s++ ) { int np = inface[s].np; // number of interface nodes if( np > 0 && s < subdom->pid ) // upstream interface nodes { int cnt = 0; for( int n=0; n<np; n++ ) { NODE* nd = inface[s].node[n]; if( !isFS(nd->flag, NODE::kDry) ) // nothing to send if node is dry... { SUB* sub = nd->sub; while( sub ) { if( sub->no == s ) break; sub = sub->next; } if( !sub->dry ) // ...or if the node is dry in { // any adjacent subdomain for( int e=0; e<df; e++ ) { int eqno = eqs->GetEqno( nd, e ); if( eqno >= 0 ) { inface[s].send[cnt] = X[eqno]; cnt++; } } } } } # ifdef _MPI_DBG { char text[200]; sprintf( text, " ### sending %d values to %d\n", cnt, s+1 ); REPORT::rpt.Output( text ); } # endif MPI_Send( &cnt, 1, MPI_INT, s, 1, MPI_COMM_WORLD ); if( cnt ) MPI_Send( inface[s].send, cnt, MPI_DOUBLE, s, 2, MPI_COMM_WORLD ); } } } # endif //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// // 2.4 MPI: backward solve for interior nodes # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Solve) starting with 2.4\n" ); # endif for( int i=neq_up-1; i>=0; i-- ) { for( int j=1; j<width[i]; j++ ) { int eq = index[i][j]; if( eq > i ) { X[i] -= ILU[i][j] * X[eq]; } } if( fabs(ILU[i][0]) < kZero ) REPORT::rpt.Error( kParameterFault, "division by zero - EQS::ILU_solver(2)" ); X[i] /= ILU[i][0]; } # ifdef kDebug { FILE* dbg; char filename[80]; MODEL* model = project->M2D; GRID* region = model->region; if( project->subdom.npr == 1 ) sprintf( filename, "backX.dbg" ); else sprintf( filename, "backX_%02d.dbg", project->subdom.pid ); dbg = fopen( filename, "w" ); fprintf( dbg, "%d\n", region->Getnp() ); for( int n=0; n<region->Getnp(); n++ ) { NODE* nd = region->Getnode( n ); for( int e=0; e<eqs->dfcn; e++ ) { fprintf( dbg, "%5d %1d ", nd->Getname(), e ); int eqno = eqs->GetEqno( nd, e ); if( eqno >= 0 ) fprintf( dbg, "%14.6le\n", X[eqno] ); else fprintf( dbg, "%14.6le\n", 0.0 ); } } fclose( dbg ); } MPI_Barrier( MPI_COMM_WORLD ); # endif # ifdef _MPI_DBG REPORT::rpt.Output( " (PRECO_ILUT::Solve) backward solve finished\n" ); # endif }
double* MODEL::Rot2D() { int np = region->Getnp(); int ne = region->Getne(); // ------------------------------------------------------------------------------------- // allocate memory for rotation of flow field // ------------------------------------------------------------------------------------- double* rot = (double*) MEMORY::memo.Array_nd( np ); double* wgt = (double*) MEMORY::memo.Array_nd( np ); for( int n=0; n<np; n++ ) rot[n] = wgt[n] = 0.0; // ------------------------------------------------------------------------------------- // loop on elements // ------------------------------------------------------------------------------------- for( int e=0; e<ne; e++ ) { ELEM* elem = region->Getelem(e); SHAPE* shape = elem->GetQShape(); int ngp = shape->ngp; // number of GAUSS points int nnd = shape->nnd; // number of corner nodes // ----------------------------------------------------------------------------------- // compute coordinates relative to first node double x[kMaxNodes2D], y[kMaxNodes2D]; x[0] = elem->nd[0]->x; y[0] = elem->nd[0]->y; for( int i=1; i<nnd; i++ ) { x[i] = elem->nd[i]->x - *x; y[i] = elem->nd[i]->y - *y; } x[0] = y[0] = 0.0; // ----------------------------------------------------------------------------------- // use GAUSS point integration to solve momentum and continuity for( int g=0; g<ngp; g++ ) { // form JACOBIAN transformation matrix --------------------------------------------- double trafo[2][2]; double* dfdxPtr = shape->dfdx[g]; double* dfdyPtr = shape->dfdy[g]; double detj = shape->jacobi2D( nnd, dfdxPtr, dfdyPtr, x, y, trafo ); double weight = detj * shape->weight[g]; // compute values of shape functions at GP g --------------------------------------- double* n = shape->f[g]; double dndx[kMaxNodes2D], dndy[kMaxNodes2D]; for( int i=0; i<nnd; i++ ) { dndx[i] = trafo[0][0] * dfdxPtr[i] + trafo[0][1] * dfdyPtr[i]; dndy[i] = trafo[1][0] * dfdxPtr[i] + trafo[1][1] * dfdyPtr[i]; } // compute flow parameters and their derivatives ----------------------------------- double dUdy = 0.0; double dVdx = 0.0; for( int i=0; i<nnd; i++ ) { NODE* node = elem->nd[i]; dUdy += dndy[i] * node->v.U; dVdx += dndx[i] * node->v.V; } // compute rotation ---------------------------------------------------------------- double f = weight * ( dVdx - dUdy ); for( int i=0; i<nnd; i++ ) { NODE* nd = elem->nd[i]; int no = nd->Getno(); rot[no] += f; wgt[no] += weight; } } } subdom->Mpi_assemble( rot ); subdom->Mpi_assemble( wgt ); // ------------------------------------------------------------------------------------- // solve for rotation for( int n=0; n<np; n++ ) { rot[n] /= wgt[n]; } // ------------------------------------------------------------------------------------- MEMORY::memo.Detach( wgt ); return rot; }
bool check(NODE &ans,NODE &begin,NODE &end) { if(ans.good()==1 && ans>=begin && end>=ans) return true; return false; }
Point operator()(const NODE& n) { // HW4B: You may change this to plot something other than the // positions of the nodes return Point(n.position().x, n.position().y, n.value().Q.h); //return n.position(); }
void EQS_KD2D::Validate( PROJECT* project, int np, NODE** node, int ne, NODE** cent, ELEM** elem ) { // ------------------------------------------------------------------------------------- // Check K and D for minmum flow velocity (Reynolds number) in surrounding nodes // define the limit of Re, where K and D will be set to their minimum double minRe = 10.0; // for each node: determine the maximum Reynolds number from surrounding nodes double* maxRe = (double*) MEMORY::memo.Array_nd( np ); for( int n=0; n<np; n++ ) { NODE* nd = node[n]; int no = nd->Getno(); double U = nd->v.U; double V = nd->v.V; double H = nd->v.S - nd->z; maxRe[no] = 4.0 * H * sqrt( U*U + V*V ) / project->vk; // check also surrounding nodes, if Reynolds number is too small at node ndi if( maxRe[no] < minRe ) { for( int j=0; j<nd->noel; j++ ) { ELEM* el = nd->el[j]; for( int k=0; k<el->Getncn(); k++ ) { NODE* ndk = el->Getnode(k); double U = ndk->v.U; double V = ndk->v.V; double H = ndk->v.S - ndk->z; double Re = H * 4.0 * sqrt( U*U + V*V ) / project->vk; if( Re > maxRe[no] ) { maxRe[no] = Re; if( maxRe[no] > minRe ) break; } } if( maxRe[no] > minRe ) break; } } } # ifdef _MPI_ project->subdom.Mpi_max( maxRe ); # endif for( int n=0; n<np; n++ ) { NODE* nd = node[n]; int no = nd->Getno(); // set the turbulence at nodes with very small Reynolds numbers to the minimum if( maxRe[no] < minRe ) { nd->v.K = project->minK; nd->v.D = project->minD; } } MEMORY::memo.Detach( maxRe ); if( quarterShape ) { for( int e=0; e<ne; e++ ) { ELEM* el = elem[e]; if( isFS( el->flag, ELEM::kRegion) && el->Getncn() == 4 ) { int no = el->Getno(); NODE* nd = cent[no]; double U = nd->v.U; double V = nd->v.V; double H = nd->v.S - nd->z; double c_maxRe = 4.0 * H * sqrt( U*U + V*V ) / project->vk; // check also surrounding nodes, if Reynolds number is too small at node ndi if( c_maxRe < minRe ) { for( int k=0; k<el->Getncn(); k++ ) { NODE* ndk = el->Getnode(k); double U = ndk->v.U; double V = ndk->v.V; double H = ndk->v.S - ndk->z; double Re = H * 4.0 * sqrt( U*U + V*V ) / project->vk; if( Re > c_maxRe ) { c_maxRe = Re; if( c_maxRe > minRe ) break; } } } // set the turbulence at nodes with very small Reynolds numbers to the minimum if( c_maxRe < minRe ) { nd->v.K = project->minK; nd->v.D = project->minD; } } } } // ------------------------------------------------------------------------------------- // try to interpolate nodes with negative values from surrounding nodes // Note: This interpolation is not so helpful in all cases. // ***PENDING*** MPI broadcasting of averaged nodal values Kave and Dave // from surrounding elements. /* GRID* rg = project->M2D->region; int* cnK = (int*) MEMORY::memo.Array_el( rg->Getne() ); int* cnD = (int*) MEMORY::memo.Array_el( rg->Getne() ); double* elK = (double*) MEMORY::memo.Array_el( rg->Getne() ); double* elD = (double*) MEMORY::memo.Array_el( rg->Getne() ); int iter; for( iter=0; iter<0; iter++ ) { int further = false; for( int e=0; e<rg->Getne(); e++ ) { ELEM* el = rg->Getelem(e); int no = el->Getno(); int ncn = el->getncn(); cnK[no] = cnD[no] = 0; elK[no] = elD[no] = 0.0; for( int i=0; i<ncn; i++ ) { NODE* nd = el->Getnode(i); if( isFS(nd->flag, NODE::kDry) ) continue; double K = nd->v.K; if( K > 0.0 ) { elK[no] += K; cnK[no]++; } double D = nd->v.D; if( D > 0.0 ) { elD[no] += D; cnD[no]++; } } } for( int n=0; n<np; n++ ) { NODE* nd = node[n]; if( nd->v.K <= 0.0 ) { further = true; int cntK = 0; double Kave = 0.0; for( int i=0; i<nd->noel; i++ ) { ELEM* el = nd->el[i]; int no = el->Getno(); if( cnK[no] ) { Kave += elK[no]; cntK += cnK[no]; } } if( cntK ) nd->v.K = Kave / cntK; } if( nd->v.D <= 0.0 ) { further = true; int cntD = 0; double Dave = 0.0; for( int i=0; i<nd->noel; i++ ) { ELEM* el = nd->el[i]; int no = el->Getno(); if( cnD[no] ) { Dave += elD[no]; cntD += cnD[no]; } } if( cntD ) nd->v.D = Dave / cntD; } } if( !further ) break; } MEMORY::memo.Detach( cnK ); MEMORY::memo.Detach( cnD ); MEMORY::memo.Detach( elK ); MEMORY::memo.Detach( elD ); if( iter ) { REPORT::rpt.Message( "\n%-25s%s %d %s\n", " (EQS_KD2D::Validate)", "interpolation of negative values in", iter, "iterations" ); } */ // ------------------------------------------------------------------------------------- // check K and D for minimum values for( int n=0; n<np; n++ ) { NODE* nd = node[n]; if( nd->v.K < project->minK || nd->v.D < project->minD ) { nd->v.K = project->minK; nd->v.D = project->minD; } } if( quarterShape ) { for( int e=0; e<ne; e++ ) { ELEM* el = elem[e]; if( isFS( el->flag, ELEM::kRegion) && el->Getncn() == 4 ) { int no = el->Getno(); NODE* nd = cent[no]; if( nd->v.K < project->minK || nd->v.D < project->minD ) { nd->v.K = project->minK; nd->v.D = project->minD; } } } } }
force_type operator()(NODE n, double t) { (void) t; force_type force = force_type(0,0,0); double mass = n.value().mass; return (force + mass * force_type(0,0,-grav)); }
bool operator()(const NODE& node1, const NODE& node2) const { Point diff1 = node1.position() - p_; Point diff2 = node2.position() - p_; if (norm(diff1) < norm(diff2)) return true; return false; }
Point operator()(const NODE& n) { return {n.position().x, n.position().y, n.value().h}; }
force_type operator()(NODE n, double t) { (void) t; Point velocity = n.value().velocity; Point return_force = -velocity/num_nodes; return Point(return_force.x,return_force.y,0); }