void ShortAxisFitting::setThetaDelta(ShortAxisOptimizationInput* input, const alglib::real_1d_array& x) { Cmiss_field_module_id field_module = (input->field_module); std::vector<Cmiss_node_id>& cmiss_nodes(*(input->cmiss_nodes)); Cmiss_field_id coordinate = (input->coordinates_rc); Cmiss_field_cache_id cache = (input->cache); double* initialSegmentLengths = input->initialSegmentLengths; int* saxNodes = input->saxNodes; int numberOfModelFrames = input->numberOfModelFrames; int NUMBER_OF_SEGMENTS = input->NUMBER_OF_SEGMENTS; int NUMBER_OF_SAX_NODES = input->NUMBER_OF_SAX_NODES; double** result = input->result; //This is expected to be preallocated for heap efficiency int* endoNodeIds = input->endoNodesIds; const int NUMBER_OF_ENDO_NODES = 48; //Ignore the apex int ctr = 0; double coord[3]; int frame = input->frame; Point3D centroids[4]; centroids[0] = input->centroids[0]; centroids[1] = input->centroids[1]; centroids[2] = input->centroids[2]; centroids[3] = input->centroids[3]; //First 12 endo nodes saxcentroid 0, next 12 1... //Set the theta variation in x to the mesh { Cmiss_field_module_begin_change(field_module); { double time = ((double) frame) / ((double) numberOfModelFrames); if (frame == (numberOfModelFrames - 1)) { time = 1.0; } Cmiss_field_cache_set_time(cache, time); for (int nc = 0; nc < NUMBER_OF_ENDO_NODES; nc++) { ctr = nc/12; double deltaTheta = ((int)(x[ctr]*100000))/100000.0; Cmiss_field_cache_set_node(cache, cmiss_nodes[endoNodeIds[nc] - 1]); Cmiss_field_evaluate_real(coordinate, cache, 3, coord); Point3D start(coord); start = start + centroids[nc/12]; double nTheta = atan2(start.z, start.x) + deltaTheta; double dist = sqrt(start.x * start.x + start.z * start.z); coord[0] = dist * cos(nTheta) - centroids[nc/12].x; coord[2] = dist * sin(nTheta) - centroids[nc/12].z; Cmiss_field_assign_real(coordinate, cache, 3, coord); } } Cmiss_field_module_end_change(field_module); } }
void StrainMeasures::embedStrainOnElements(std::string fieldname, std::vector<std::string>& strain) { const unsigned int num_strains = numberOfModelFrames_; double times[1024]; for (unsigned int j = 0; j < num_strains; j++) { times[j] = static_cast<double>(j) / (num_strains - 1.0); } Cmiss_time_sequence_id time_sequence = Cmiss_field_module_get_matching_time_sequence(field_module, num_strains, times); Cmiss_field_module_begin_change(field_module); //Create Node template Cmiss_nodeset_id nodeset = Cmiss_field_module_find_nodeset_by_name(field_module, "cmiss_nodes"); Cmiss_node_template_id nodeTemplate = Cmiss_nodeset_create_node_template(nodeset); //Create the field Cmiss_field_id strainField = Cmiss_field_module_create_field(field_module, fieldname.c_str(), "finite number_of_components 1 component_names value"); if (!strainField) { std::cout << "Unable to create field " << fieldname << std::endl; return; } Cmiss_node_template_define_field(nodeTemplate, strainField); Cmiss_node_template_define_time_sequence(nodeTemplate, strainField, time_sequence); //Create Element template Cmiss_mesh_id mesh = Cmiss_field_module_find_mesh_by_dimension(field_module, 3); Cmiss_element_template_id element_template = Cmiss_mesh_create_element_template(mesh); Cmiss_element_template_set_shape_type(element_template, CMISS_ELEMENT_SHAPE_CUBE); Cmiss_element_template_set_number_of_nodes(element_template, 1); Cmiss_element_basis_id constant_basis = Cmiss_field_module_create_element_basis(field_module, 3, CMISS_BASIS_FUNCTION_CONSTANT); const int local_node_index = 1; Cmiss_element_template_define_field_simple_nodal(element_template, strainField, -1, constant_basis, 1, &local_node_index); Cmiss_element_basis_destroy(&constant_basis); //Map strains to elements std::map<int, int> elemStrainMap; //Cmiss element no is mapped to strain array number //APLAX elemStrainMap[3] = elemStrainMap[10] = 1; //Array id base 0 elemStrainMap[15] = elemStrainMap[22] = 18; //Average of strain ids 2 and 8 elemStrainMap[27] = elemStrainMap[34] = 12; elemStrainMap[39] = elemStrainMap[46] = 17; elemStrainMap[40] = elemStrainMap[45] = 17; elemStrainMap[28] = elemStrainMap[33] = 10; elemStrainMap[16] = elemStrainMap[21] = 19; //Average of strain ids 11 and 5 elemStrainMap[4] = elemStrainMap[9] = 4; //TCH elemStrainMap[11] = elemStrainMap[12] = 2; //Array id base 0 elemStrainMap[23] = elemStrainMap[24] = 20; //Average of strain ids 3 and 9 elemStrainMap[35] = elemStrainMap[36] = 8; elemStrainMap[47] = elemStrainMap[48] = 16; elemStrainMap[41] = elemStrainMap[42] = 16; elemStrainMap[17] = elemStrainMap[18] = 11; elemStrainMap[29] = elemStrainMap[30] = 21; //Average of strain ids 12 and 6 elemStrainMap[5] = elemStrainMap[6] = 5; //FCH elemStrainMap[1] = elemStrainMap[2] = 3; //Array id base 0 elemStrainMap[13] = elemStrainMap[14] = 22; //Average of 10 and 4 elemStrainMap[25] = elemStrainMap[26] = 4; elemStrainMap[37] = elemStrainMap[38] = 23; //Average of strains 14 and 15 elemStrainMap[43] = elemStrainMap[44] = 24; //Average of strains 16 and 13 elemStrainMap[31] = elemStrainMap[32] = 6; elemStrainMap[19] = elemStrainMap[20] = 25; //Average of strains 7 and 1 elemStrainMap[7] = elemStrainMap[8] = 0; std::vector<std::string> allStrain = strain; //Add the additional strains 18 - 23 std::string s2 = strain[1]; std::string s8 = strain[7]; std::string s11 = strain[10]; std::string s5 = strain[5]; std::string s9 = strain[8]; std::string s3 = strain[2]; std::string s12 = strain[11]; std::string s6 = strain[6]; std::string s10 = strain[9]; std::string s4 = strain[3]; std::string s14 = strain[13]; std::string s15 = strain[14]; std::string s16 = strain[15]; std::string s13 = strain[12]; std::string s1 = strain[0]; std::string s7 = strain[6]; std::vector<std::string> compute; compute.push_back(s2); compute.push_back(s8); compute.push_back(s11); compute.push_back(s5); compute.push_back(s9); compute.push_back(s3); compute.push_back(s12); compute.push_back(s6); compute.push_back(s10); compute.push_back(s4); compute.push_back(s14); compute.push_back(s15); compute.push_back(s16); compute.push_back(s13); compute.push_back(s7); compute.push_back(s1); for (int cptc = 0; cptc < 16; cptc += 2) { std::vector<std::string> strain1; std::vector<std::string> strain2; std::ostringstream ss; boost::split(strain1, compute[cptc], boost::is_any_of(",")); boost::split(strain2, compute[cptc + 1], boost::is_any_of(",")); for (unsigned int j = 0; j < num_strains - 1; j++) { double value1 = atof(strain1[j].c_str()); double value2 = atof(strain2[j].c_str()); ss << (value1 + value2) * 0.5 << ","; } ss << "0.0"; allStrain.push_back(ss.str()); } for (unsigned int i = 0; i < num_elements; i++) { Cmiss_node_id temporaryNode = Cmiss_nodeset_create_node(nodeset, extraNodeStartID++, nodeTemplate); Cmiss_element_template_set_node(element_template, 1, temporaryNode); //Link node with the element Cmiss_element_merge(elements[i], element_template); Cmiss_field_cache_set_node(fieldCache, temporaryNode); std::vector<std::string> strains; boost::split(strains, allStrain[elemStrainMap[i + 1]], boost::is_any_of(",")); for (unsigned int j = 0; j < num_strains; j++) { double value = atof(strains[j].c_str()); double time = times[j]; Cmiss_field_cache_set_time(fieldCache, time); Cmiss_field_assign_real(strainField,fieldCache,1,&value); } Cmiss_node_destroy(&temporaryNode); } Cmiss_field_module_end_change(field_module); Cmiss_field_destroy(&strainField); Cmiss_element_template_destroy(&element_template); Cmiss_node_template_destroy(&nodeTemplate); Cmiss_nodeset_destroy(&nodeset); //Calling the following leads to the error ERROR: DESTROY(FE_time_sequence). Positive access_count //Cmiss_time_sequence_destroy(&time_sequence); }
void ShortAxisFitting::optimize(const alglib::real_1d_array& x, double& func, void* ptr) { struct ShortAxisOptimizationInput* input = static_cast<struct ShortAxisOptimizationInput*>(ptr); Cmiss_field_module_id field_module = (input->field_module); std::vector<Cmiss_node_id>& cmiss_nodes(*(input->cmiss_nodes)); std::vector<double>& targetDeltas(*(input->targetDeltas)); Cmiss_field_id coordinate = (input->coordinates_rc); Cmiss_field_cache_id cache = (input->cache); double* initialSegmentLengths = input->initialSegmentLengths; int* saxNodes = input->saxNodes; int numberOfModelFrames = input->numberOfModelFrames; int NUMBER_OF_SEGMENTS = input->NUMBER_OF_SEGMENTS; int NUMBER_OF_SAX_NODES = input->NUMBER_OF_SAX_NODES; double** result = input->result; //This is expected to be preallocated for heap efficiency int* endoNodeIds = input->endoNodesIds; const int NUMBER_OF_ENDO_NODES = 48; //Ignore the apex int ctr = 0; double coord[3]; int frame = input->frame; std::vector<Point3D>& resetCoord(input->initEndoCoordinates->at(frame)); std::vector<Point3D>& initFrame(*input->initFrame); setThetaDelta(input, x); //Compute the theta error double thetaError = 0.0; //for (int frame = 0; frame < numberOfModelFrames; frame++) { double time = ((double) frame) / ((double) numberOfModelFrames); if (frame == (numberOfModelFrames - 1)) { time = 1.0; } Cmiss_field_cache_set_time(cache, time); std::vector<Point3D> sax; Point3D sax_centroid(0, 0, 0); for (int seg = 0; seg < NUMBER_OF_SAX_NODES; seg++) { Cmiss_field_cache_set_node(cache, cmiss_nodes[saxNodes[seg]]); Cmiss_field_evaluate_real(coordinate, cache, 3, coord); Point3D start(coord); sax.push_back(start); sax_centroid += start; } sax_centroid = sax_centroid * (1.0 / NUMBER_OF_SAX_NODES); double avg = 0.0; for (int seg = 0; seg < NUMBER_OF_SAX_NODES; seg++) { Vector3D trans = sax[seg] - sax_centroid; double denom = trans.x- initFrame[seg].x; double nuem = trans.z- initFrame[seg].z; double ltheta = atan2(nuem, denom); if(fabs(denom)<1.0e-6 && fabs(nuem)<1.0e-6){ ltheta = 0.0; } avg += ltheta; } avg /=NUMBER_OF_SAX_NODES; thetaError +=fabs(avg-targetDeltas[frame]); input->thetaError = avg; } //Compute the segment error getSegmentLengths(input); double segmentMatchError = input->segmentMatchError; func = segmentMatchError + thetaError; if(segmentMatchError>2.0) func = 1.0e+30; input->totalError = func; //Reset coordinates to original { Cmiss_field_module_begin_change(field_module); { double time = ((double) frame) / ((double) numberOfModelFrames); if (frame == (numberOfModelFrames - 1)) { time = 1.0; } Cmiss_field_cache_set_time(cache, time); for (int nc = 0; nc < NUMBER_OF_ENDO_NODES; nc++) { coord[0] = resetCoord[nc].x; coord[1] = resetCoord[nc].y; coord[2] = resetCoord[nc].z; Cmiss_field_cache_set_node(cache, cmiss_nodes[endoNodeIds[nc] - 1]); Cmiss_field_assign_real(coordinate, cache, 3, coord); } } Cmiss_field_module_end_change(field_module); } }
inline int Field::assignReal(FieldCache& cache, int numberOfValues, const double *values) { return Cmiss_field_assign_real(id, cache.getId(), numberOfValues, values); }