void FieldVariableDescriptor::MergeArrays(TArray<FieldVariableDescriptor> & dest, const TArray<FieldVariableDescriptor> & source) { // in case of a performance loss this function should be rewritten with dictionaries (maps) and hash codes for(int j = 1; j <= source.Length(); j++) { const FieldVariableDescriptor & fvd = source(j); int i; int cmp = 1; for(i = 1; i <= dest.Length(); i++) { cmp = fvd.Compare(dest(i)); if(cmp != 1) break; // found either the same entry or the point where this entry is to be inserted } if(cmp != 0) dest.Insert(i, fvd); } }
int FieldVariableDescriptor::FindTypeInArray( TArray<FieldVariableDescriptor> & fvd_array, // array FieldVariableType variable_type, // type of the added variables FieldVariableComponentIndex component_index_1, // component 1 FieldVariableComponentIndex component_index_2 // component 2 (if relevant) ) { int rv = 0; FieldVariableDescriptor fvd(variable_type, component_index_1, component_index_2); for(int i=1; i<=fvd_array.Length(); i++) { if (!fvd.Compare(fvd_array(i))) { return i; } } return rv; }
int Generate_Model_ANCFCable2D_contact(MBS* mbs) { ElementDataContainer* edc = mbs->GetModelDataContainer(); int nel = edc->TreeGetInt("Geometry.n_fibers"); double sx = edc->TreeGetDouble("Geometry.length"); double sy = edc->TreeGetDouble("Geometry.width"); int nx = edc->TreeGetInt("Geometry.nx"); int ny = edc->TreeGetInt("Geometry.ny"); double rho = edc->TreeGetDouble("Geometry.rho"); double Em = edc->TreeGetDouble("Geometry.Em"); double nu = edc->TreeGetDouble("Geometry.nu"); double box_x = edc->TreeGetDouble("Geometry.box_x"); double box_y = edc->TreeGetDouble("Geometry.box_y"); int nbox_x = edc->TreeGetInt("Geometry.nres_x"); int nbox_y = edc->TreeGetInt("Geometry.nres_y"); Vector3D size(sx,sy,1.0); double cdim = sy/2; double wi = 1; //width of GeomLine2D elements (in pts/pixel) //===============================2D fibers========================================= ANCFCable2D cable(mbs); Vector xc1(4); Vector xc2(4); double phi = -MY_PI/4.; xc1(1)=0.5*sx*cos(phi+MY_PI); xc1(2)=0.5*sx*sin(phi+MY_PI); xc1(3)=cos(phi); xc1(4)=sin(phi); xc2(1)=xc1(1)+sx*cos(phi); xc2(2)=xc1(2)+sx*sin(phi); xc2(3)=cos(phi); xc2(4)=sin(phi); //Material m1(mbs,rho,Em,nu); //int mat1 = mbs->AddMaterial(&m1); cable.SetANCFCable2D(xc1, xc2, rho, Em, size, Vector3D(0.,0.7,0.)); //cable.SetANCFCable2D(xc1, xc2, vcenter, vcenter, n1, n2, rho, Em, size, Vector3D(0.,0.7,0.)); int nr = mbs->AddElement(&cable); MBSLoad grav; grav.SetBodyLoad(-9.81*rho,2); mbs->GetElement(nr).AddLoad(grav); //MBSSensor force_x(mbs,TMBSSensor(TSElement+TSDOF),idx1,1); //measure force via Lagrange multiplier //force_x.SetSensorName(mystr("Node_")+mystr(i)+mystr("_force_x")); //mbs->AddSensor(&force_x); TArray<Vector2D> points; double dx = sx/nx; double dy = sy/ny; for(int i=0; i<nx; ++i) points.Add(Vector2D(-0.5*sx+i*dx,-0.5*sy)); for(int i=0; i<ny; ++i) points.Add(Vector2D(0.5*sx,-0.5*sy+i*dy)); for(int i=0; i<nx; ++i) points.Add(Vector2D(0.5*sx-i*dx,0.5*sy)); for(int i=0; i<=ny; ++i) points.Add(Vector2D(-0.5*sx,0.5*sy-i*dy)); //mbs->GetElement(nr).SetAltShape(1); ////sensors for nodal positions and velocities //MBSSensor s1(mbs,TMBSSensor(TSElement+TSplanar+TSPos+TSX),nr,Vector3D(-0.5*size.X(),0.,0.)); //s1.SetSensorName(mystr("Node_")+mystr(i)+mystr("_x")); //mbs->AddSensor(&s1); //sensors //field variables not available? //{ // FieldVariableElementSensor s1(mbs); // s1.SetFVESPos2D(nr,FieldVariableDescriptor(FieldVariableDescriptor::FieldVariableType::FVT_position,FieldVariableDescriptor::FieldVariableComponentIndex::FVCI_x),Vector2D(0.)); // s1.SetSensorName(mystr("cable")+mystr("_x")); // mbs->AddSensor(&s1); // FieldVariableElementSensor s2(mbs); // s2.SetFVESPos2D(nr,FieldVariableDescriptor(FieldVariableDescriptor::FieldVariableType::FVT_position,FieldVariableDescriptor::FieldVariableComponentIndex::FVCI_y),Vector2D(0.)); // s2.SetSensorName(mystr("cable")+mystr("_y")); // mbs->AddSensor(&s2); // FieldVariableElementSensor s3(mbs); // s3.SetFVESPos2D(nr,FieldVariableDescriptor(FieldVariableDescriptor::FieldVariableType::FVT_velocity,FieldVariableDescriptor::FieldVariableComponentIndex::FVCI_x),Vector2D(0.)); // s3.SetSensorName(mystr("cable")+mystr("_vx")); // mbs->AddSensor(&s3); // FieldVariableElementSensor s4(mbs); // s4.SetFVESPos2D(nr,FieldVariableDescriptor(FieldVariableDescriptor::FieldVariableType::FVT_velocity,FieldVariableDescriptor::FieldVariableComponentIndex::FVCI_y),Vector2D(0.)); // s4.SetSensorName(mystr("cable")+mystr("_vy")); // mbs->AddSensor(&s4); //} //contact Vector3D contactcol(0.5,0,0.5); int slaveNODEmode = 0; //if NODEmode = 1, then use locnodenumbers, if NODEmode==0 then use loccoords double bordersize = 0.25*sy; //additional search radius for master and slave segments/nodes GeneralContact2D gc(mbs, slaveNODEmode, bordersize, Vector3D(0.0005,0,0), contactcol); gc.SetContactMode(0); //0 for Hertzian contact with restitution coefficient gc.SetIsLagrange(0); double friccoeff = 0.2; gc.SetFriction(1, edc->TreeGetDouble("Geometry.friction_coeff")); gc.SetContactParams(edc->TreeGetDouble("Geometry.restitution_coeff"),1); //coefficient of restitution, Hertzian contact parameter gc.SetContactMaxDist(0.5*sy); //max penetration; if exceeded, it is treated as if there where no contact gc.SetSearchTreeDim(20,20); double cstiff = edc->TreeGetDouble("Geometry.contact_stiffness"); int bodyind = 1; for(int i=1; i<points.Length(); ++i) { gc.AddSlaveNode(nr, points(i), cstiff, bodyind); } if(edc->TreeGetInt("Geometry.mutual_contact")) { for(int i=1; i<points.Length(); ++i) { gc.AddMasterSegment(nr,points(i),points(i+1),bodyind); //be careful with orientation of master segments } } //===============================rigid body==================================== { Vector x0i(6); x0i(1)=0.; x0i(2)=0.25*box_y; x0i(3)=0.; x0i(4)=0.; x0i(5)=0.; x0i(6)=0.; double r0=0.3*sx; Vector3D sizei(r0,r0,1.); Vector3D coli(1.,0.,0.); Rigid2D testbody(mbs,x0i,rho,sizei,coli); int nr = mbs->AddElement(&testbody); //MBSLoad load; //load.SetForceVector2D(Vector2D(1e-4,2e-4),Vector2D(0.)); mbs->GetElement(nr).AddLoad(grav); TArray<Vector2D> points; int ni = 32; for(int j=0; j<=ni; ++j) points.Add(Vector2D( r0*cos(2*MY_PI/ni*j), r0*sin(2*MY_PI/ni*j) )); //for better visualization of rotation GeomLine2D c1(mbs,nr,Vector2D(0.,-0.5*r0),Vector2D(0.,0.5*r0),Vector3D(1.,0.,0.)); GeomLine2D c2(mbs,nr,Vector2D(-0.5*r0,0.),Vector2D(0.5*r0,0.),Vector3D(1.,0.,0.)); c1.SetDrawParam(Vector3D(2*wi, 10., 0.)); c2.SetDrawParam(Vector3D(2*wi, 10., 0.)); mbs->GetElement(nr).Add(c1); mbs->GetElement(nr).Add(c2); mbs->GetElement(nr).SetAltShape(1); //sensors //{ // FieldVariableElementSensor s1(mbs); // s1.SetFVESPos2D(nr,FieldVariableDescriptor(FieldVariableDescriptor::FieldVariableType::FVT_position,FieldVariableDescriptor::FieldVariableComponentIndex::FVCI_x),Vector2D(0.)); // s1.SetSensorName(mystr("rigid")+mystr("_x")); // mbs->AddSensor(&s1); // FieldVariableElementSensor s2(mbs); // s2.SetFVESPos2D(nr,FieldVariableDescriptor(FieldVariableDescriptor::FieldVariableType::FVT_position,FieldVariableDescriptor::FieldVariableComponentIndex::FVCI_y),Vector2D(0.)); // s2.SetSensorName(mystr("rigid")+mystr("_y")); // mbs->AddSensor(&s2); // FieldVariableElementSensor s3(mbs); // s3.SetFVESPos2D(nr,FieldVariableDescriptor(FieldVariableDescriptor::FieldVariableType::FVT_velocity,FieldVariableDescriptor::FieldVariableComponentIndex::FVCI_x),Vector2D(0.)); // s3.SetSensorName(mystr("rigid")+mystr("_vx")); // mbs->AddSensor(&s3); // FieldVariableElementSensor s4(mbs); // s4.SetFVESPos2D(nr,FieldVariableDescriptor(FieldVariableDescriptor::FieldVariableType::FVT_velocity,FieldVariableDescriptor::FieldVariableComponentIndex::FVCI_y),Vector2D(0.)); // s4.SetSensorName(mystr("rigid")+mystr("_vy")); // mbs->AddSensor(&s4); //} ////lock rotation //if(edc->TreeGetInt("Geometry.lock_rigid_body_rotation")) //{ // CoordConstraint cc1(mbs, nr, 3, cdim); // mbs->AddElement(&cc1); //} //contact bodyind = 2; for(int i=1; i<=points.Length(); ++i) { gc.AddSlaveNode(nr, points(i), cstiff, bodyind); } if(edc->TreeGetInt("Geometry.mutual_contact")) { for(int i=1; i<points.Length(); ++i) { gc.AddMasterSegment(nr,points(i),points(i+1),bodyind); //be careful with orientation of master segments GeomLine2D c1(mbs,nr,points(i),points(i+1),Vector3D(1.,0.,0.)); c1.SetDrawParam(Vector3D(2*wi, 10., 0.)); mbs->GetElement(nr).Add(c1); } } } //===============================frame========================================= points.Flush(); dx = box_x/nbox_x; dy = box_y/nbox_y; for(int i=0; i<nbox_x; ++i) points.Add(Vector2D(-0.5*box_x+i*dx,-0.5*box_y)); for(int i=0; i<nbox_y; ++i) points.Add(Vector2D(0.5*box_x,-0.5*box_y+i*dy)); for(int i=0; i<nbox_x; ++i) points.Add(Vector2D(0.5*box_x-i*dx,0.5*box_y)); for(int i=0; i<=nbox_y; ++i) points.Add(Vector2D(-0.5*box_x,0.5*box_y-i*dy)); //contact bodyind = 0; //must be 0 for mbs for(int i=1; i<points.Length(); ++i) { gc.AddMasterSegment(0,points(i+1),points(i), bodyind); //be careful with orientation of master segments GeomLine2D c1(mbs,0,points(i+1),points(i),Vector3D(0.,0.,0.)); c1.SetDrawParam(Vector3D(2*wi, 10., 0.)); mbs->Add(c1); } //finish contact gc.FinishContactDefinition(); mbs->AddElement(&gc); mbs->Assemble(); return 1; };
void Quadrilateral::SetQuadrilateral(int bodyindi, const TArray<int>& nodelist, int material_num, double thickness, const Vector3D& coli) { assert(nodelist.Length() == 4 || nodelist.Length() == 9); // Quadrilateral, number of nodes in the set function is invalid FiniteElement2D::SetFiniteElement2D(bodyindi, nodelist, material_num, thickness, coli); SetGeometricNonlinearityStatus(GNS_Linear); }
void D3DObjectImage::EndCache(D3DDevice *d3d) { if (!_cache_enabled || _cache.Length() == 0) return; D3DShaderPack::Current()->SetVDecl(d3d, D3DShaderPack::VDECL_XYUVC); D3DShaderPack::Current()->SetVS(d3d, D3DShaderPack::VS_COPY_UV_COLOR); D3DShaderPack::Current()->SetPS(d3d, D3DShaderPack::PS_TEX_COLOR_FILTER); static TArray<Vertex> sorted; static TArray<GroupDesc> groups; sorted.Allocate(0); groups.Allocate(0); bool found = true; while (found) { found = false; int cur_id = -1; int num = 0; for (int i = 0; i < _cache.Length(); i++) { // We have processed this if (_cache[i]->_image_id < 0) continue; found = true; if (cur_id < 0) cur_id = _cache[i]->_image_id; if (_cache[i]->_image_id == cur_id) { if (!_cache[i]->_with_border) { Vertex *data = _cache[i]->MakeData(); sorted.Add(data[0]); sorted.Add(data[1]); sorted.Add(data[2]); sorted.Add(data[3]); sorted.Add(data[4]); sorted.Add(data[5]); _cache[i]->_image_id = -_cache[i]->_image_id - 1; num++; } else { Vertex *data = _cache[i]->MakeDataBorder(); int last_len = sorted.Length(); sorted.Allocate(last_len + 6 * 9); CopyMemory(&sorted[last_len], data, sizeof(Vertex) * 6 * 9); _cache[i]->_image_id = -_cache[i]->_image_id - 1; num += 9; } } } if (num > 0) { GroupDesc gd = {num, cur_id}; groups.Add(gd); } } // Restore ids for (int i = 0; i < _cache.Length(); i++) _cache[i]->_image_id = -_cache[i]->_image_id - 1; D3DVertexBufferCache::CacheEntryInfo ce_info; if (!D3DVertexBufferCache::Current()->InitBuffer(d3d, (BYTE *)sorted.Data(), sorted.Length() * sizeof(Vertex), ce_info)) { return; } D3DVertexBufferCache::Current()->SelectBufferToDevice(d3d, ce_info.id, sizeof(Vertex)); HRESULT hr; for (int i = 0, cur = 0; i < groups.Length(); i++) { if (FAILED(hr = D3DImageCache::Current()->SelectImageToDevice(d3d, groups[i].id))) { Log("Failed to select texture: %X", (DWORD)hr); } // d3d->GetDevice()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, groups[i].num * 2, // &sorted[cur], sizeof(Vertex)); d3d->GetDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, cur, groups[i].num * 2); cur += groups[i].num * 6; } DBG("Image cache drawn: %d items, %d groups", _cache.Length(), groups.Length()); _cache_enabled = false; }