// transform MCOORD prime primitive velocity to whichcoord whichvel velocity int metp2met2bl(int whichvel, int whichcoord, FTYPE *pr, int ii, int jj) { int k = 0; FTYPE ucon[NDIM]; struct of_geom geom; // which=WHICHVEL // which==0 means supplied the 4-velocity // which==1 means supplied the 3-velocity // which==2 means supplied the relative 4-velocity // if whichcood==PRIMECOORDS, then just pr2ucon and ucon2pr // effectively this results in changing from one primitive velocity to another within PRIMECOORDS // get prime MCOORD geometry get_geometry(ii,jj,CENT,&geom) ; // transform prime MCOORD primitive to prim MCOORD 4-vel if (pr2ucon(WHICHVEL,pr, &geom ,ucon) >= 1) FAILSTATEMENT("init.c:init()", "pr2ucon()", 1); if(whichcoord>=0){ // transform from prime MCOORD 4-vel to non-prime MCOORD 4-vel metptomet(ii,jj,ucon); // transform from non-prime MCOORD to non-prime whichcoord coordtrans(MCOORD,whichcoord,ii,jj,ucon); } // else already in prime // transform from non-prime whichcoord 4-vel to non-prime whichcoord whichvel-velocity gset(0,whichcoord,ii,jj,&geom); ucon2pr(whichvel,ucon,&geom,pr); return(0); }
int main(int argc, char* argv[]) { if (argc != 5) { printf("Usage: %s from to lng lat\n", argv[0]); return 1; } double lng = atof(argv[3]); double lat = atof(argv[4]); double newlng = 0; double newlat = 0; int ret = coordtrans(argv[1], argv[2], lng, lat, newlng, newlat); if (ret == 0) { printf("%lf\t%lf\t%lf,%lf\n", newlng, newlat, newlng, newlat); return 0; } else { printf("failed to convert from %s to %s\n", argv[1], argv[2]); return 1; } }
// converts whichvel/whichcoord velocity to WHICHVEL/MCOORD int bl2met2metp2v(int whichvel, int whichcoord, FTYPE *pr, int ii, int jj) { int k = 0; FTYPE ucon[NDIM]; struct of_geom geom; // whichvel==0 means supplied the 4-velocity // whichvel==1 means supplied the 3-velocity // whichvel==2 means supplied the relative 4-velocity // if whichcoord==PRIMECOORDS, then really use uses pr2ucon and ucon2pr, could probably optimize if wanted // effectively this results in changing from one primitive velocity to another within PRIMECOORDS // pr is in whichcoord coordinates // get geometry (non-prime coords) gset(0,whichcoord,ii,jj,&geom); // convert whichvel-pr in whichcoord coords to ucon in whichcoord coordinates if (pr2ucon(whichvel,pr, &geom ,ucon) >= 1) FAILSTATEMENT("init.c:init()", "pr2ucon()", 1); // convert from whichcoord to MCOORD, the coordinates of evolution if(whichcoord>=0){ coordtrans(whichcoord,MCOORD,ii,jj,ucon); // transform MCOORD ucon from MCOORD non-prime to MCOORD prime coords mettometp(ii,jj,ucon); } // otherwise already in prime // get prime geometry get_geometry(ii,jj,CENT,&geom) ; // convert from MCOORD prime 4-vel to MCOORD prime WHICHVEL-vel(i.e. primitive velocity of evolution) ucon2pr(WHICHVEL,ucon,&geom,pr); return(0); }
int wind_power_calculator::wind_power(/*INPUTS */ double dWindSpeed, double dWindDirDeg, double dAirPressureAtm, double TdryC, /*OUTPUTS*/ double *FarmP, double aPower[], double aThrust[], double aEff[], double adWindSpeed[], double aTI[], double aDistanceDownwind[], double aDistanceCrosswind[]) { if ( (m_iNumberOfTurbinesInFarm > MAX_WIND_TURBINES) || (m_iNumberOfTurbinesInFarm < 1) ) { m_sErrDetails = "The number of wind turbines was greater than the maximum allowed in the wake model."; return 0; } size_t i,j; //unsigned char wt_id[MAX_WIND_TURBINES], wid; // unsigned char has 256 limit size_t wt_id[MAX_WIND_TURBINES], wid; for (i=0; i<m_iNumberOfTurbinesInFarm; i++) wt_id[i] = i; // convert barometric pressure in ATM to air density double fAirDensity = (dAirPressureAtm * physics::Pa_PER_Atm)/(physics::R_Gas * physics::CelciusToKelvin(TdryC)); //!Air Density, kg/m^3 double fTurbine_output, fThrust_coeff; turbine_power(dWindSpeed, fAirDensity, &fTurbine_output, &fThrust_coeff ); // initialize values before possible exit from the function for (i=0;i<m_iNumberOfTurbinesInFarm;i++) { aPower[i] = 0.0; aThrust[i] = 0.0; aEff[i] = 0.0; adWindSpeed[i] = dWindSpeed; aTI[i] = m_dTurbulenceIntensity; } // if there is only one turbine, we're done if (m_iNumberOfTurbinesInFarm < 2) { *FarmP = fTurbine_output; return 1; } // if power output of first turbine is zero, then it will be for the rest: we're done if (fTurbine_output <= 0.0) { *FarmP = 0.0; return (int)m_iNumberOfTurbinesInFarm; } // ok, let's calculate the farm output //!Convert to d (downwind - axial), c (crosswind - radial) coordinates double d, c; //std::vector<double> aDistanceDownwind(m_iNumberOfTurbinesInFarm); // downwind coordinate of each WT //std::vector<double> aDistanceCrosswind(m_iNumberOfTurbinesInFarm); // crosswind coordinate of each WT for (i=0;i<m_iNumberOfTurbinesInFarm;i++) { coordtrans(m_adYCoords[i], m_adXCoords[i], dWindDirDeg, &d, &c ); aDistanceDownwind[i] = d; aDistanceCrosswind[i] = c; } // Remove negative numbers from downwind, crosswind coordinates double Dmin = aDistanceDownwind[0]; double Cmin = aDistanceCrosswind[0]; for (j=1;j<m_iNumberOfTurbinesInFarm;j++) { Dmin = min_of(aDistanceDownwind[j],Dmin); Cmin = min_of(aDistanceCrosswind[j],Cmin); } for (j=0;j<m_iNumberOfTurbinesInFarm;j++) { aDistanceDownwind[j] = aDistanceDownwind[j]-Dmin; // Final downwind coordinates, meters aDistanceCrosswind[j] = aDistanceCrosswind[j]-Cmin; // Final crosswind coordinates, meters } // Convert downwind, crosswind measurements from meters into wind turbine radii for (i=0;i<m_iNumberOfTurbinesInFarm;i++) { aDistanceDownwind[i] = 2.0*aDistanceDownwind[i]/m_dRotorDiameter; aDistanceCrosswind[i] = 2.0*aDistanceCrosswind[i]/m_dRotorDiameter; } // Record the output for the most upwind turbine (already calculated above) aPower[0] = fTurbine_output; aThrust[0] = fThrust_coeff; aEff[0] = ( fTurbine_output < 1.0 ) ? 0.0 : 100.0; // Sort aDistanceDownwind, aDistanceCrosswind arrays by downwind distance, aDistanceDownwind[0] is smallest downwind distance, presumably zero for (j=1;j<m_iNumberOfTurbinesInFarm;j++) { d = aDistanceDownwind[j]; // pick out each element c = aDistanceCrosswind[j]; wid = wt_id[j]; i=j; while (i > 0 && aDistanceDownwind[i-1] > d) // look for place to insert item { aDistanceDownwind[i] = aDistanceDownwind[i-1]; aDistanceCrosswind[i] = aDistanceCrosswind[i-1]; wt_id[i] = wt_id[i-1]; i--; } aDistanceDownwind[i] = d; // insert it aDistanceCrosswind[i] = c; wt_id[i] = wid; } // run the wake model switch (m_iWakeModelChoice) { case PAT_QUINLAN_WAKE_MODEL: wake_calculations_pat_quinlan_mod(fAirDensity, &aDistanceDownwind[0], &aDistanceCrosswind[0], aPower, aThrust, aEff, adWindSpeed, aTI); break; case PARK_WAKE_MODEL: wake_calculations_Park(fAirDensity, &aDistanceDownwind[0], &aDistanceCrosswind[0], aPower, aThrust, aEff, adWindSpeed); break; case SIMPLE_EDDY_VISCOSITY_WAKE_MODEL: if (!wake_calculations_EddyViscosity_Simple(fAirDensity, &aDistanceDownwind[0], &aDistanceCrosswind[0], aPower, aThrust, aEff, adWindSpeed, aTI)) return 0; break; case OLD_PQ: wake_calculations_pat_quinlan_old(fAirDensity, &aDistanceDownwind[0], &aDistanceCrosswind[0], aPower, aThrust, aEff, adWindSpeed, aTI); break; default: m_sErrDetails = "Unknown wake model encountered in wind_power_calculator::wind_power."; return 0; } // calculate total farm power *FarmP = 0; for (i=0;i<m_iNumberOfTurbinesInFarm;i++) *FarmP += aPower[i]; // Update down/cross wind distance units for turbine zero (convert from radii to meters) aDistanceDownwind[0] *= m_dRotorDiameter/2; aDistanceCrosswind[0] *= m_dRotorDiameter/2; // Resort output arrays by wind turbine ID (0..nwt-1) // for consistent reporting double p,t,e,w,b,dd,dc; for (j=1;j<m_iNumberOfTurbinesInFarm;j++) { p = aPower[j];// pick out each element t = aThrust[j]; e = aEff[j]; w = adWindSpeed[j]; b = aTI[j]; dd = aDistanceDownwind[j] * m_dRotorDiameter/2; // convert back to meters from radii dc = aDistanceCrosswind[j] * m_dRotorDiameter/2; wid = wt_id[j]; i=j; while (i > 0 && wt_id[i-1] > wid) // look for place to insert item { aPower[i] = aPower[i-1]; aThrust[i] = aThrust[i-1]; aEff[i] = aEff[i-1]; adWindSpeed[i] = adWindSpeed[i-1]; aTI[i] = aTI[i-1]; aDistanceDownwind[i] = aDistanceDownwind[i-1]; aDistanceCrosswind[i] = aDistanceCrosswind[i-1]; wt_id[i] = wt_id[i-1]; i--; } aPower[i] = p; aThrust[i] = t; aEff[i] = e; adWindSpeed[i] = w; aTI[i] = b; aDistanceDownwind[i] = dd; aDistanceCrosswind[i] = dc; wt_id[i] = wid; } return (int)m_iNumberOfTurbinesInFarm; }
void Common::SelectParticle() { // cout << "----------------------" << endl; // cout << "SelectParticle: r: " << r << endl; vector<int> curlist = data.getCurrentList(); vector<int>::iterator p; Particle candPt; double candPtDist = TARGET_DIST_THRESH/scale; float wandpos_tmp1[3],wandpos_tmp2[3]; float wandvec_tmp1[3],wandvec_tmp2[3]; CAVEGetPosition(CAVE_WAND_NAV, wandpos_tmp1); CAVEGetVector(CAVE_WAND_FRONT_NAV,wandvec_tmp1); PARTICLE_POS candPos; PARTICLE_POS crossPos; for(int i=0;i<3;i++){ candPos.pos[i] = -100; } for (int i = 0; i < 3; i++) { wandpos_tmp1[i] -= (float) ORIG[i]; } coordtrans(wandpos_tmp1,wandpos_tmp2,rot); coordtrans(wandvec_tmp1,wandvec_tmp2,rot); for (p = curlist.begin(); p != curlist.end(); p++) { PARTICLE_POS pos; double dist; if (*p < 0) { continue; } Particle *pt = data.getData(*p); pt->extrapolate(t_dat,scale,&pos); for (int i = 0; i < 3; i++) { crossPos.pos[i] = wandpos_tmp2[i]+(BEAM_SCALE*wandvec_tmp2[i]); } dist = GetParticleDist(&pos,&crossPos); if(dist < TARGET_DIST_THRESH/scale&&dist < candPtDist){ candPt = *pt; for(int i=0;i<3;i++){ candPos.pos[i] = pos.pos[i]; } } } if(candPt.getId()==-1){ return; } if(target_id.empty()|| (target_id.front()!=candPt.getId()&&target_id.back()!=candPt.getId())){ target_id.push(candPt.getId()); vector<TARGET_POS> pos_vector; traj.push(pos_vector); } if(target_id.size()==3 ||(target_id.size()==2&&target_id.front()==target_id.back()) ){ target_id.pop(); traj.pop(); } return; }
int main() { //malha geometrica TPZGeoMesh *firstmesh = new TPZGeoMesh; firstmesh->SetName("Malha Geometrica : Nós e Elementos"); firstmesh->NodeVec().Resize(4); TPZVec<REAL> coord(2),coordtrans(2); REAL ct,st,PI=3.141592654; cout << "\nEntre rotacao do eixo n1 (graus) -> "; REAL g; cin >> g; g = g*PI/180.; ct = cos(g); st = sin(g); //ct = 1.; //st = 0.; coord[0] = 0; coord[1] = 0; coordtrans[0] = ct*coord[0]-st*coord[1]; coordtrans[1] = st*coord[0]+ct*coord[1]; //nos geometricos firstmesh->NodeVec()[0].Initialize(coordtrans,*firstmesh); coord[0] = 5; coordtrans[0] = ct*coord[0]-st*coord[1]; coordtrans[1] = st*coord[0]+ct*coord[1]; firstmesh->NodeVec()[1].Initialize(coordtrans,*firstmesh); coord[0] = 5; coord[1] = 5; coordtrans[0] = ct*coord[0]-st*coord[1]; coordtrans[1] = st*coord[0]+ct*coord[1]; firstmesh->NodeVec()[2].Initialize(coordtrans,*firstmesh); coord[0] = 0; coordtrans[0] = ct*coord[0]-st*coord[1]; coordtrans[1] = st*coord[0]+ct*coord[1]; firstmesh->NodeVec()[3].Initialize(coordtrans,*firstmesh); /* TPZVec<int> nodeindexes(3); nodeindexes[0] = 0; nodeindexes[1] = 1; nodeindexes[2] = 2; //elementos geometricos TPZGeoElT2d *elg0 = new TPZGeoElT2d(nodeindexes,1,*firstmesh); nodeindexes[0] = 0; nodeindexes[1] = 2; nodeindexes[2] = 3; TPZGeoElT2d *elg1 = new TPZGeoElT2d(nodeindexes,1,*firstmesh); nodeindexes[0] = 0; nodeindexes[1] = 1; nodeindexes[2] = 2; TPZGeoElT2d *elg2 = new TPZGeoElT2d(nodeindexes,2,*firstmesh); nodeindexes[0] = 0; nodeindexes[1] = 2; nodeindexes[2] = 3; TPZGeoElT2d *elg3 = new TPZGeoElT2d(nodeindexes,2,*firstmesh); */ TPZVec<int> nodeindexes(4); nodeindexes[0] = 0; nodeindexes[1] = 1; nodeindexes[2] = 2; nodeindexes[3] = 3; //elementos geometricos TPZGeoEl *elg0 = new TPZGeoElQ2d(nodeindexes,1,*firstmesh); TPZGeoEl *elg1 = new TPZGeoElQ2d(nodeindexes,2,*firstmesh); TPZGeoEl *elg2 = new TPZGeoElQ2d(nodeindexes,3,*firstmesh); //Arquivos de saida ofstream outgm1("outgm1.dat"); ofstream outcm1("outcm1.dat"); ofstream outcm2("outcm2.dat"); //montagem de conectividades entre elementos firstmesh->BuildConnectivity(); //malha computacional TPZCompMesh *secondmesh = new TPZCompMesh(firstmesh); secondmesh->SetName("Malha Computacional : Conectividades e Elementos"); //material TPZMaterial *pl = LerMaterial("placa1.dat"); secondmesh->InsertMaterialObject(pl); pl = LerMaterial("placa2.dat"); secondmesh->InsertMaterialObject(pl); pl = LerMaterial("placa3.dat"); secondmesh->InsertMaterialObject(pl); //CC : condicões de contorno TPZBndCond *bc; REAL big = 1.e12; TPZFMatrix val1(6,6,0.),val2(6,1,0.); val1(0,0)=big; val1(1,1)=big; val1(2,2)=big; val1(3,3)=0.; val1(4,4)=0.; val1(5,5)=0.; TPZGeoElBC(elg0,5,-2,*firstmesh); bc = pl->CreateBC(-2,2,val1,val2); secondmesh->InsertMaterialObject(bc); TPZGeoElBC(elg0,6,-3,*firstmesh); bc = pl->CreateBC(-3,2,val1,val2); secondmesh->InsertMaterialObject(bc); val1(0,0)=0.; val1(1,1)=big; val1(2,2)=0.; val1(3,3)=big; val1(4,4)=0.; val1(5,5)=0.; TPZGeoElBC(elg0,4,-1,*firstmesh); bc = pl->CreateBC(-1,2,val1,val2); secondmesh->InsertMaterialObject(bc); val1(0,0)=big; val1(1,1)=0.; val1(2,2)=0.; val1(3,3)=0.; val1(4,4)=big; val1(5,5)=0.; TPZGeoElBC(elg0,7,-4,*firstmesh); bc = pl->CreateBC(-4,2,val1,val2); secondmesh->InsertMaterialObject(bc); //ordem de interpolacao int ord; cout << "Entre ordem 1,2,3,4,5 : "; cin >> ord; // TPZCompEl::gOrder = ord; cmesh.SetDefaultOrder(ord); //construção malha computacional TPZVec<int> csub(0); TPZManVector<TPZGeoEl *> pv(4); int n1=1,level=0; cout << "\nDividir ate nivel ? "; int resp; cin >> resp; int nelc = firstmesh->ElementVec().NElements(); int el; TPZGeoEl *cpel; for(el=0;el<firstmesh->ElementVec().NElements();el++) { cpel = firstmesh->ElementVec()[el]; if(cpel && cpel->Level() < resp) cpel->Divide(pv); } //analysis secondmesh->AutoBuild(); secondmesh->AdjustBoundaryElements(); secondmesh->InitializeBlock(); secondmesh->Print(outcm1); TPZAnalysis an(secondmesh,outcm1); int numeq = secondmesh->NEquations(); secondmesh->Print(outcm1); outcm1.flush(); TPZVec<int> skyline; secondmesh->Skyline(skyline); TPZSkylMatrix *stiff = new TPZSkylMatrix(numeq,skyline); an.SetMatrix(stiff); an.Solver().SetDirect(ECholesky); secondmesh->SetName("Malha Computacional : Connects e Elementos"); // Posprocessamento an.Run(outcm2); TPZVec<char *> scalnames(5); scalnames[0] = "Mn1"; scalnames[1] = "Mn2"; scalnames[2] = "Sign1"; scalnames[3] = "Sign2"; scalnames[4] = "Deslocz"; TPZVec<char *> vecnames(0); char plotfile[] = "placaPos.pos"; char pltfile[] = "placaView.plt"; an.DefineGraphMesh(2, scalnames, vecnames, plotfile); an.Print("FEM SOLUTION ",outcm1); an.PostProcess(2); an.DefineGraphMesh(2, scalnames, vecnames, pltfile); an.PostProcess(2); firstmesh->Print(outgm1); outgm1.flush(); delete secondmesh; delete firstmesh; return 0; }