void DRMLoadPattern::applyLoad(double time) { DRMBoundaryLayerDecorator *myDecorator = new DRMBoundaryLayerDecorator(); myDecorator->setDomain(this->getDomain()); Vector U(24); Vector Ud(24); Vector Udd(24); Vector load(24); U.Zero(); Ud.Zero(); Udd.Zero(); load.Zero(); myDecorator->setMap(this->eNodes); for(std::map<int,Element*>::iterator pos=this->elem.begin(); pos!=this->elem.end(); pos++) { int eleTag = pos->first; Element* ele = (Element*) pos->second; if (ele != 0) { U.Zero(); Ud.Zero(); Udd.Zero(); load.Zero(); myDecorator->setBrick(ele); this->myHandler->getMotions(ele, time, U, Ud, Udd); myDecorator->applyDRMLoad(this->factor,load, U, Ud, Udd); } } delete myDecorator; }
float vtt_sim( void ) { int j; float f, g, h, p, q, sound, sound_decim; /*** compute da and dx with a new area function, and Ud=d(A*x)/dt ***/ if( vocal_tract == TIME_VARYING) { dax(); if( dynamic_term == ON ) Ud(); } /*** Simulate deci (=simfrq/smpfrq) cycles with interpolation of a and x ***/ for(j=0; j<deci; j++) { /*** solve s = Wx ***/ if( nasal_tract == ON ) { elimination_t(1, nph3, eqph); elimination_t(0, nbu3, eqbu); elimination_t(0, nna3, eqna); f = eqph[nph3].S/eqph[nph3].W; g = eqbu[nbu3].S/eqbu[nbu3].W; h = eqna[nna3].S/eqna[nna3].W; p = f + g + h; f = eqph[nph2].W/eqph[nph3].W; g = eqbu[nbu2].W/eqbu[nbu3].W; h = eqna[nna2].W/eqna[nna3].W; q = f + g + h; eqph[nph4].x = eqbu[nbu4].x = eqna[nna4].x = p/q; substitution_t(1, nph3, eqph); substitution_t(0, nbu3, eqbu); substitution_t(0, nna3, eqna); } else { elimination_t(1, nph3, eqph); elimination_t(0, nbu3, eqbu); f = eqph[nph3].S/eqph[nph3].W; g = eqbu[nbu3].S/eqbu[nbu3].W; p = f + g; f = eqph[nph2].W/eqph[nph3].W; g = eqbu[nbu2].W/eqbu[nbu3].W; q = f + g; eqph[nph4].x = eqbu[nbu4].x = p/q; substitution_t(1, nph3, eqph); substitution_t(0, nbu3, eqbu); } /*** Refresh acoustic and matrix elements ***/ if( vocal_tract == TIME_VARYING ) { /* pharyngeal tract */ acou_mtrx( nph, afph, dph, acph, eqph, 0., 0.); /* bucal cavity */ acou_mtrx( nbu, afbu, dbu, acbu, eqbu, 0., 0.); if( rad_boundary == RL_CIRCUIT ) { Grad_lips = Grad*afbu[0].A; Lrad_lips = (float)(Srad*sqrt(afbu[0].A)); eqbu[0].w = Grad_lips + Lrad_lips; } else eqbu[0].w = 10.0; /* short circuit */ /* nasal inlet */ acou_mtrx(1, afnc, dnc, acna+nna-1, eqna+2*(nna-1), Rs_na, Ls_na); } /* add the glottal resistance (it alwalys time_varying) */ Ag = nonzero_t( Ag ); eqph[1].w = (float)(acph[0].Rs + acph[0].Ls + (Rv*xg/Ag + Rk*fabs(eqph[1].x))/(Ag*Ag)); /*** Refresh force constants ***/ force_constants(nph, acph, eqph); eqph[1].s = acph[0].els + H2O_bar*Psub; /* right arm */ if( rad_boundary == RL_CIRCUIT ) irad_lips = (float)(2.0*Lrad_lips*eqbu[0].x + irad_lips); force_constants(nbu, acbu, eqbu); eqbu[0].s = -irad_lips; /* rad. admitance */ eqbu[1].s = acbu[0].els; /* right arm */ U0_lips = U1_lips; U1_lips = -eqbu[1].x; sound = U1_lips - U0_lips; if( nasal_tract == ON ) { if( rad_boundary == RL_CIRCUIT ) irad_nose = (float)(2.0*Lrad_nose*eqna[0].x + irad_nose); force_constants(nna, acna, eqna); eqna[0].s = -irad_nose; /* rad. admitance */ eqna[1].s = acna[0].els; /* right arm */ U0_nose = U1_nose; U1_nose = -eqna[1].x; sound = sound + U1_nose - U0_nose; } /*** decimation of the radiated sound ***/ if( j == deci - 1 ) sound_decim = decim( 1, Kr*sound ); else decim( 0, Kr*sound ); } /*** return the radiated sound pressure ***/ return( sound_decim ); }
CC_FILE_ERROR MascaretFilter::saveToFile(ccHObject* entity, QString filename, SaveParameters& parameters) { if (!entity || filename.isEmpty()) return CC_FERR_BAD_ARGUMENT; //look for valid profiles std::vector<ccPolyline*> profiles; try { //get all polylines std::vector<ccPolyline*> candidates; if (entity->isA(CC_TYPES::POLY_LINE)) { candidates.push_back(static_cast<ccPolyline*>(entity)); } else if (entity->isA(CC_TYPES::HIERARCHY_OBJECT)) { for (unsigned i=0; i<entity->getChildrenNumber(); ++i) if (entity->getChild(i) && entity->getChild(i)->isA(CC_TYPES::POLY_LINE)) candidates.push_back(static_cast<ccPolyline*>(entity->getChild(i))); } //then keep the valid profiles only for (size_t i=0; i<candidates.size(); ++i) { ccPolyline* poly = candidates[i]; if ( !poly->hasMetaData(ccPolyline::MetaKeyUpDir()) || !poly->hasMetaData(ccPolyline::MetaKeyAbscissa()) || !poly->hasMetaData(ccPolyline::MetaKeyPrefixCenter()+".x") || !poly->hasMetaData(ccPolyline::MetaKeyPrefixCenter()+".y") || !poly->hasMetaData(ccPolyline::MetaKeyPrefixCenter()+".z") || !poly->hasMetaData(ccPolyline::MetaKeyPrefixDirection()+".x") || !poly->hasMetaData(ccPolyline::MetaKeyPrefixDirection()+".y") || !poly->hasMetaData(ccPolyline::MetaKeyPrefixDirection()+".z") ) { ccLog::Warning(QString("[Mascaret] Polyline '%1' is not a valid profile (missing meta-data)").arg(poly->getName())); break; } else { profiles.push_back(poly); } } } catch (const std::bad_alloc&) { return CC_FERR_NOT_ENOUGH_MEMORY; } if (profiles.empty()) return CC_FERR_NO_SAVE; //open ASCII file for writing QFile file(filename); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return CC_FERR_WRITING; QTextStream outFile(&file); outFile.setRealNumberPrecision(12); //ask some parameters SaveMascaretFileDlg smfDlg; if (!smfDlg.exec()) return CC_FERR_CANCELED_BY_USER; QString biefName = smfDlg.biefNameLineEdit->text(); QString type("T"); //B or T --> ask the user switch(smfDlg.typeComboBox->currentIndex()) { case 0: type = "B"; //bathy break; case 1: type = "T"; //topo break; default: assert(false); } //sanitize the 'bief' (reach) name biefName = MakeMascaretName(biefName); //sort the sections by their abscissa if (profiles.size() > 1) { for (size_t i=0; i<profiles.size()-1; ++i) { size_t smallestIndex = i; double smallestAbscissa = profiles[i]->getMetaData(ccPolyline::MetaKeyAbscissa()).toDouble(); for (size_t j=i+1; j<profiles.size(); ++j) { double a = profiles[j]->getMetaData(ccPolyline::MetaKeyAbscissa()).toDouble(); if (a < smallestAbscissa) { smallestAbscissa = a; smallestIndex = j; } } if (i != smallestIndex) { std::swap(profiles[i],profiles[smallestIndex]); } } } CC_FILE_ERROR result = CC_FERR_NO_SAVE; //for each profile for (size_t i=0; i<profiles.size(); ++i) { ccPolyline* poly = profiles[i]; unsigned vertCount = poly ? poly->size() : 0; if (vertCount < 2) { //invalid size ccLog::Warning(QString("[Mascaret] Polyline '%1' does not have enough vertices").arg(poly->getName())); continue; } //decode meta-data bool ok = true; int upDir = 2; double absc = 0.0; CCVector3d Cd(0,0,0); CCVector3d Ud(0,0,0); while (true) //fake loop for easy break { upDir = poly->getMetaData(ccPolyline::MetaKeyUpDir()).toInt(&ok); if (!ok) break; absc = poly->getMetaData(ccPolyline::MetaKeyAbscissa()).toDouble(&ok); if (!ok) break; Cd.x = poly->getMetaData(ccPolyline::MetaKeyPrefixCenter()+".x").toDouble(&ok); if (!ok) break; Cd.y = poly->getMetaData(ccPolyline::MetaKeyPrefixCenter()+".y").toDouble(&ok); if (!ok) break; Cd.z = poly->getMetaData(ccPolyline::MetaKeyPrefixCenter()+".z").toDouble(&ok); if (!ok) break; Ud.x = poly->getMetaData(ccPolyline::MetaKeyPrefixDirection()+".x").toDouble(&ok); if (!ok) break; Ud.y = poly->getMetaData(ccPolyline::MetaKeyPrefixDirection()+".y").toDouble(&ok); if (!ok) break; Ud.z = poly->getMetaData(ccPolyline::MetaKeyPrefixDirection()+".z").toDouble(&ok); break; } if (!ok) { ccLog::Warning(QString("[Mascaret] At least one of the meta-data entry of polyline '%1' is invalid?!").arg(poly->getName())); continue; } QString profileName = poly->getName(); profileName = MakeMascaretName(profileName); CCVector3 C = CCVector3::fromArray(Cd.u); CCVector3 U = CCVector3::fromArray(Ud.u); U.normalize(); //write header outFile << "PROFIL " << biefName << " " << profileName << " " << absc; #define SAVE_AS_GEO_MASCARET #ifdef SAVE_AS_GEO_MASCARET int xDir = upDir == 2 ? 0 : upDir+1; int yDir = xDir == 2 ? 0 : xDir+1; //for "geo"-mascaret, we add some more information: // - first point { const CCVector3* firstP = poly->getPoint(0); CCVector3d firstPg = poly->toGlobal3d(*firstP); outFile << " "; outFile << firstPg.u[xDir] << " " << firstPg.u[yDir]; } // - last point { const CCVector3* lastP = poly->getPoint(vertCount-1); CCVector3d lastPg = poly->toGlobal3d(*lastP); outFile << " "; outFile << lastPg.u[xDir] << " " << lastPg.u[yDir]; } // - profile/path intersection point { outFile << " AXE "; CCVector3d Cdg = poly->toGlobal3d(Cd); outFile << Cdg.u[xDir] << " " << Cdg.u[yDir]; } #endif outFile << endl; //check the abscissa values order (must be increasing!) bool inverted = false; { const CCVector3* P0 = poly->getPoint(0); //convert to 'local' coordinate system CCVector2 Q0; ToLocalAbscissa(*P0, C, U, upDir, Q0); const CCVector3* P1 = poly->getPoint(vertCount-1); //convert to 'local' coordinate system CCVector2 Q1; ToLocalAbscissa(*P1, C, U, upDir, Q1); inverted = (Q1.x < Q0.x); } for (unsigned j=0; j<vertCount; ++j) { const CCVector3* P = poly->getPoint(inverted ? vertCount-1-j : j); //convert to 'local' coordinate system CCVector2 Q; ToLocalAbscissa(*P, C, U, upDir, Q); outFile << Q.x << " " << Q.y << " " << type; #ifdef SAVE_AS_GEO_MASCARET { //for "geo"-mascaret, we add some more information: // - real coordinates of the point outFile << " "; CCVector3d Pg = poly->toGlobal3d(*P); outFile << Pg.u[xDir] << " " << Pg.u[yDir]; } #endif outFile << endl; } result = CC_FERR_NO_ERROR; } file.close(); return result; }