void KVTensP::Copy(TObject& a) const #else void KVTensP::Copy(TObject& a) #endif { // // Methode de Copy // KVVarGlob::Copy(a); ((KVTensP&) a).SetZmin(GetZmin()); ((KVTensP&) a).SetTensor(GetTensor()); }
//****************************************************************************** //Name: GetTensor * // * //Purpose: get the tensor portion of the field given the position * // * //Takes: position stored as a tensor * //****************************************************************************** tensor field::GetTensor(const tensor &pos) { int i; double position[3]; tensor temp; for( i = 0; i < 3; i++ ) position[i] = pos.Val(i); temp <= GetTensor(position); return temp; }
//****************************************************************************** //Name: SetInterpTensor * // * //Purpose: set the grid tensors based on interpolation from a tensor at an * // arbitrary position * // * //Takes: pointer to the position array and address of the rval tensor * //****************************************************************************** void field::SetInterpTensor(double *position, const tensor &rval) { int step; int i, j, k; int scaled_pos[3]; int grid_pos[3]; double pos[3]; tensor dummy, temp; step = 1; out_of_range = FALSE; //Set the reference position for(i = 0; i < 3; i++) reference_pos[i] = position[i]; //Get the double indices for the scaled position GetIndices(reference_pos, scaled_pos); //step through the floor steping while( !out_of_range ) { for( i = 0; i < 2; i++) { for( j = 0; j < 2; j++) { for( k = 0; k < 2; k++) { grid_pos[0] = (int)floor( scaled_pos[0] + i * step ); grid_pos[1] = (int)floor( scaled_pos[1] + j * step ); grid_pos[2] = (int)floor( scaled_pos[2] + k * step ); GetPosition(grid_pos, pos); dummy <= GetTensor(pos); temp <= rval; temp.ScalarMult(Smoother(PARTICLE_SMOOTHING)); dummy <= dummy + temp; if( out_of_range ) break; } } } //temp hack to keep the interpolation to within one cell out_of_range = TRUE; } }
//****************************************************************************** //Name: GetInterpTensor * // * //Purpose: get the interpolated tensor at an arbitrary position * // * //Takes: pointer to the position array * //****************************************************************************** tensor field::GetInterpTensor(double *position) { int i, j, k, m, n; double scaled_pos[3]; int grid_pos[3]; double W; if( is_series_set == FALSE ) error("GetInterpTensor error:","series not set"); //initialize member data tensors sum_Wm <= 0.0*sum_Wm; sum_a2 <= 0.0*sum_a2; sum_da1 <= 0.0*sum_da1; d_sum_a2 <= 0.0*d_sum_a2; out_of_range = FALSE; //Set the reference position for(i = 0; i < 3; i++) reference_pos[i] = position[i]; //Get the real indices for the scaled position GetIndices(reference_pos, scaled_pos); //Create the return tensor and set it to zero ret_dummy <= 0.0*GetTensor(reference_pos); //Reset the normalization normalization = 0.0; //step through the floor steping for( i = grid_lower_bound; i < grid_upper_bound; i++) { for( j = grid_lower_bound; j < grid_upper_bound; j++) { for( k = grid_lower_bound; k < grid_upper_bound; k++) { //Get the indices of the lowest corner of the cell grid_pos[0] = (int)floor( scaled_pos[0] + i ); grid_pos[1] = (int)floor( scaled_pos[1] + j ); grid_pos[2] = (int)floor( scaled_pos[2] + k ); //find the position this grid point GetPosition(grid_pos,current_pos); //form the difference array and its magnitude (for use by smoother) //and the difference position y = 0; for( m = 0; m < 3; m++ ) { pos_diff[m] = reference_pos[m] - current_pos[m]; y += pos_diff[m]*pos_diff[m]; d.Set(pos_diff[m], m); } y = sqrt(y)/smoothing_length; if( y > 1.0 + SMOOTHING_TOL ) continue; //get all of the tensors requested by the order for( m = 0; m <= series.order; m++) tmp[m] <= series.list[m]->GetTensor(grid_pos); //get the (psuedo) scalar smoothing value W = Smoother(CWM_SMOOTHER); //if the field is basic (i.e. not a derivative of //another field) if( is_deriv_field == FALSE ) { if( series.order == 2 ) { m = tmp[2].NumIndices() - 1; tmp[2] <= 0.5 *( tmp[2].Contract(d,m,0) ).Contract(d,m-1,0); } if( series.order == 1 || series.order == 2 ) { m = tmp[1].NumIndices() - 1; tmp[1] <= tmp[1].Contract(d,m,0); } for( m = 0; m <= series.order; m++) ret_dummy <= ret_dummy + W*tmp[m]; } //if the field is not basic (i.e. is a derivative of //another field if( is_deriv_field == TRUE ) { //if the field is independent (i.e. its smoothing is not //a derivative of the smoohting of its basic field if( is_dep_field == FALSE ) { temp0 <= 0.0*tmp[0]; if( series.order == 1 ) { m = tmp[1].NumIndices() - 1; temp0 <= tmp[1].Contract(d,m,0); } ret_dummy <= ret_dummy + W*(tmp[0] + temp0); } //if the field is dependent (i.e. it smoothing is //based on the derivative of the smoothing of its basic field else { temp0 <= 0.0*tmp[0]; if( series.order == 2 ) { m = tmp[2].NumIndices() - 1; //form the 1/2 * t,ij*(z-x)_i*(z-x)_j term if neccessary temp0 <= 0.5*( tmp[2].Contract(d,m,0) ).Contract(d,m-1,0); } temp1 <= 0.0*tmp[0]; if( series.order ==1 || series.order == 2 ) { n = tmp[1].NumIndices() - 1; //form the t,i*(z-x)_i term if neccessary temp1 <= tmp[1].Contract(d,n,0); //form the t,i + t,ij*(z-x)_j temp2 <= 0.0*tmp[1]; if( series.order == 2 ) temp2 <= tmp[2].Contract(d,m,0); sum_da1 <= sum_da1 + W*(tmp[1] + temp2); } //form the t + t,i*(z-x)_i + 1/2 * t,ij*(z-x)_i*(z-x)_j a2 <= tmp[0] + temp1 + temp0; sum_a2 <= sum_a2 + W*a2; //get the derivative of the smoothing Wm <= Smoother_Deriv(CWM_SMOOTHER); //keep running sum sum_Wm <= sum_Wm + Wm; //form the term labeled dN_D_2 in the MathCAD d_sum_a2 <= d_sum_a2 + a2 * Wm; } } } } } //Normalize the interpolated tensor if( is_dep_field == FALSE ) ret_dummy <= (1.0/normalization)*ret_dummy; if( is_dep_field == TRUE ) { ret_dummy <= normalization * ( sum_da1 + d_sum_a2 ) - sum_a2 * sum_Wm; ret_dummy <= 1.0/(normalization*normalization) * ret_dummy; } return ret_dummy; }