ShortAxisFitting::~ShortAxisFitting() { for (int i = 0; i < NUMBER_OF_NODES; i++) { Cmiss_node_destroy(&cmiss_nodes[i]); } Cmiss_field_cache_destroy(&cache); Cmiss_field_destroy(&coordinates_rc_); Cmiss_field_module_destroy(&field_module_); Cmiss_context_destroy(&context_); delete[] initialSegmentLengths; for (int i = 0; i < 24; i++) { delete[] segmentNodes[i]; } delete[] segmentNodes; }
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); }
std::vector<std::string> StrainMeasures::getSegmentStrains(std::string fieldName) { std::vector<std::string> strains(19); Cmiss_field_id field = Cmiss_field_module_find_field_by_name(field_module, fieldName.c_str()); //Compute strains unsigned int numSegments = mySegments->size(); double temp_array1[3]; double temp_array2[3]; //#define printcoord #ifdef printcoord #include "MeshTopology.h" std::vector<Cmiss_node_id> myNodes(100); Cmiss_nodeset_id nodeset = Cmiss_field_module_find_nodeset_by_name(field_module, "cmiss_nodes"); Cmiss_node_iterator_id nodeIterator = Cmiss_nodeset_create_node_iterator(nodeset); Cmiss_node_id node = Cmiss_node_iterator_next(nodeIterator); if (node != 0) { double temp_array[3]; while (node) { int node_id = Cmiss_node_get_identifier(node); myNodes[node_id - 1] = node; node = Cmiss_node_iterator_next(nodeIterator); } } Cmiss_nodeset_destroy(&nodeset); Cmiss_node_iterator_destroy(&nodeIterator); std::vector<int> Nodes(27); Nodes[8] = aplaxNodes8; Nodes[7] = aplaxNodes7; Nodes[6] = aplaxNodes6; Nodes[5] = aplaxNodes5; Nodes[4] = aplaxNodes4; Nodes[3] = aplaxNodes3; Nodes[2] = aplaxNodes2; Nodes[1] = aplaxNodes1; Nodes[0] = aplaxNodes0; Nodes[9] = tchNodes0; Nodes[10] = tchNodes1; Nodes[11] = tchNodes2; Nodes[12] = tchNodes3; Nodes[13] = tchNodes4; Nodes[14] = tchNodes5; Nodes[15] = tchNodes6; Nodes[16] = tchNodes7; Nodes[17] = tchNodes8; Nodes[18] = fchNodes0; Nodes[19] = fchNodes1; Nodes[20] = fchNodes2; Nodes[21] = fchNodes3; Nodes[22] = fchNodes4; Nodes[23] = fchNodes5; Nodes[24] = fchNodes6; Nodes[25] = fchNodes7; Nodes[26] = fchNodes8; #endif std::vector<std::vector<double> > aplaxLengths; std::vector<std::vector<double> > tchLengths; std::vector<std::vector<double> > fchLengths; double denomj = (numberOfModelFrames_ - 1.0); for (int i = 0; i < numberOfModelFrames_; i++) { std::vector<double> cLengths; double time = ((double) i) / denomj; Cmiss_field_cache_set_time(fieldCache, time); #ifdef printcoord std::cout<<"Frame "<<i<<"\t"<<time<<"\t"<<mySegments->at(0).xia[2]<<std::endl; #endif for (int j = 0; j < numSegments; j++) { WallSegment& seg = mySegments->at(j); //The the lengths temp_array1[0] = temp_array1[1] = temp_array1[2] = 0.0; temp_array2[0] = temp_array2[1] = temp_array2[2] = 0.0; //Since cmiss id starts at 1 subtract 1 from seg.elemeid? //Note that accessing some computed field (those that involve gradients), with multiple versions leads to gradient set to 0 warning Cmiss_field_cache_set_mesh_location(fieldCache, elements[seg.elementida - 1], 3, seg.xia); Cmiss_field_evaluate_real(field, fieldCache, 3, temp_array1); Cmiss_field_cache_set_mesh_location(fieldCache, elements[seg.elementidb - 1], 3, seg.xib); Cmiss_field_evaluate_real(field, fieldCache, 3, temp_array2); Point3D p1(temp_array1); Point3D p2(temp_array2); double dist = p1.distance(p2); #ifdef printcoord { int nodeCtr = (j / 8) * 9 + j % 8; Cmiss_field_cache_set_node(fieldCache, myNodes[Nodes[nodeCtr]]); temp_array1[0] = temp_array1[1] = temp_array1[2] = 0.0; Cmiss_field_evaluate_real(field, fieldCache, 3, temp_array1); Point3D p3(temp_array1); Cmiss_field_cache_set_node(fieldCache, myNodes[Nodes[nodeCtr + 1]]); temp_array1[0] = temp_array1[1] = temp_array1[2] = 0.0; Cmiss_field_evaluate_real(field, fieldCache, 3, temp_array1); Point3D p4(temp_array1); std::cout << p1 << "\t" << p2 << " = " << dist << "\t:\t Value at " << Nodes[nodeCtr] + 1 << "\t" << p3 << "\t" << p1.distance(p3) << "\t" << Nodes[nodeCtr + 1] + 1 << "\t" << p4 << "\t" << p2.distance(p4) << "\t distance \t " << p3.distance(p4) << std::endl; } #endif cLengths.push_back(dist); } for (int segc = 0; segc < numSegments / 8; segc++) { int offset = segc * 8; std::vector<double> sLengths; sLengths.push_back(cLengths[0 + offset] + (1 / 3.0 - 1 / 4.0) * 4 * cLengths[1 + offset]); sLengths.push_back((1.0 - (1 / 3.0 - 1 / 4.0)) * 4 * cLengths[1 + offset] + (2 / 3.0 - 1 / 2.0) * 4 * cLengths[2 + offset]); sLengths.push_back((1.0 - (2 / 3.0 - 1 / 2.0)) * 4 * cLengths[2 + offset] + cLengths[3 + offset]); sLengths.push_back(cLengths[4 + offset] + (1.0 - (2 / 3.0 - 1 / 2.0)) * 4 * cLengths[5 + offset]); sLengths.push_back((2 / 3.0 - 1 / 2.0) * 4 * cLengths[5 + offset] + (1.0 - (1 / 3.0 - 1 / 4.0)) * 4 * cLengths[6 + offset]); sLengths.push_back((1 / 3.0 - 1 / 4.0) * 4 * cLengths[6 + offset] + cLengths[7 + offset]); if (segc == 0) aplaxLengths.push_back(sLengths); else if (segc == 1) tchLengths.push_back(sLengths); else fchLengths.push_back(sLengths); } } std::vector<double> avgStrains(numberOfModelFrames_, 0.0); for (int segc = 0; segc < numSegments / 8; segc++) { std::vector<std::vector<double> > dstrains; std::vector<std::vector<double> > distances; if (segc == 0) distances = aplaxLengths; else if (segc == 1) distances = tchLengths; else if (segc == 2) distances = fchLengths; std::vector<double>& initStrain = distances[0]; for (int frame = 1; frame < numberOfModelFrames_; frame++) { //Compute Strains std::vector<double>& curStrainLengths = distances[frame]; std::vector<double> curStrain; double c = 0; unsigned int ulimit = initStrain.size(); for (int j = 0; j < ulimit; j++) { c = 100.0 * (curStrainLengths[j] - initStrain[j]) / initStrain[j]; curStrain.push_back(c); } dstrains.push_back(curStrain); } std::vector<std::string> strainSeries; for (int j = 0; j < initStrain.size(); j++) { std::ostringstream ss; ss << 0.0; //For init step int denom = numberOfModelFrames_ - 1; double maxStrain = dstrains[denom - 1][j]; //Note that frame goes from 1 to heart.numberOfModelFrames_ when computing strain //so shift down by 1 for (int i = 0; i < denom; i++) { //Compute Strains //Drift compensate double stc = dstrains[i][j] - (i + 1) * maxStrain / denom; ss << "," << stc; avgStrains[i] += stc; } strainSeries.push_back(ss.str()); } if (segc == 0) { strains[2 - 1] = strainSeries[5]; strains[8 - 1] = strainSeries[4]; strains[17 - 1] = strainSeries[3]; strains[18 - 1] = strainSeries[2]; strains[11 - 1] = strainSeries[1]; strains[5 - 1] = strainSeries[0]; } else if (segc == 2) { strains[3 - 1] = strainSeries[0]; strains[9 - 1] = strainSeries[1]; strains[14 - 1] = strainSeries[2]; strains[16 - 1] = strainSeries[3]; strains[12 - 1] = strainSeries[4]; strains[6 - 1] = strainSeries[5]; } else if (segc == 1) { strains[4 - 1] = strainSeries[0]; strains[10 - 1] = strainSeries[1]; strains[15 - 1] = strainSeries[2]; strains[13 - 1] = strainSeries[3]; strains[7 - 1] = strainSeries[4]; strains[1 - 1] = strainSeries[5]; } } #ifdef printcoord std::cout << "Linear 3D " << fieldName << std::endl; for (int i = 1; i < 100; i++) Cmiss_node_destroy(&myNodes[i]); #endif //Add the average strain //Num strain segments depends on the number of active segments (6 strain segments per view, which has 8 active segments) double denom = (numSegments / 8) * 6; std::ostringstream ss; ss << 0.0; //For init step for (int i = 0; i < numberOfModelFrames_ - 1; i++) { //Compute the Average ss << "," << avgStrains[i] / denom; } strains[18] = ss.str(); //Check if model PGS should be calculated if (computeModelPGS) { double max = fabs(avgStrains[0]); int idx = 0; for (int i = 1; i < numberOfModelFrames_ - 1; i++) { if (fabs(avgStrains[i]) > max) { max = fabs(avgStrains[i]); idx = i; } } modelPGS = avgStrains[idx] / denom; computeModelPGS = false; //set it so that it is not computed in subsequent calls } Cmiss_field_destroy(&field); return strains; }
int define_Computed_field_type_nodal_lookup(struct Parse_state *state, void *field_modify_void, void *computed_field_lookup_package_void) /******************************************************************************* LAST MODIFIED : 25 August 2006 DESCRIPTION : Converts <field> into type COMPUTED_FIELD_NODAL_LOOKUP (if it is not already) and allows its contents to be modified. ==============================================================================*/ { int return_code; Computed_field_lookup_package *computed_field_lookup_package; Computed_field_modify_data *field_modify; if (state&&(field_modify=(Computed_field_modify_data *)field_modify_void) && (computed_field_lookup_package= (Computed_field_lookup_package *) computed_field_lookup_package_void)) { return_code = 1; Cmiss_field_id source_field = 0; char *nodeset_name = duplicate_string("cmiss_nodes"); char node_flag = 0; int node_identifier = 0; if ((NULL != field_modify->get_field()) && (computed_field_nodal_lookup_type_string == Computed_field_get_type_string(field_modify->get_field()))) { Cmiss_node_id lookup_node = 0; return_code = Computed_field_get_type_nodal_lookup(field_modify->get_field(), &source_field, &lookup_node); if (source_field) { ACCESS(Computed_field)(source_field); } if (lookup_node) { node_identifier = get_FE_node_identifier(lookup_node); FE_region *fe_region = FE_node_get_FE_region(lookup_node); if (!FE_region_contains_FE_node(fe_region, lookup_node)) { DEALLOCATE(nodeset_name); nodeset_name = duplicate_string("cmiss_data"); } node_flag = 1; } } Option_table *option_table = CREATE(Option_table)(); /* source field */ Set_Computed_field_conditional_data set_source_field_data; set_source_field_data.computed_field_manager = field_modify->get_field_manager(); set_source_field_data.conditional_function = Computed_field_has_numerical_components; set_source_field_data.conditional_function_user_data = (void *)NULL; Option_table_add_entry(option_table,"field", &source_field, &set_source_field_data,set_Computed_field_conditional); /* the node to nodal_lookup */ Option_table_add_entry(option_table, "node", &node_identifier, &node_flag, set_int_and_char_flag); /* the nodeset the node is from */ Option_table_add_string_entry(option_table, "nodeset", &nodeset_name, " NODE_GROUP_FIELD_NAME|[GROUP_NAME.]cmiss_nodes|cmiss_data[cmiss_nodes]"); return_code = Option_table_multi_parse(option_table,state); DESTROY(Option_table)(&option_table); if (return_code && node_flag) { Cmiss_nodeset_id nodeset = Cmiss_field_module_find_nodeset_by_name(field_modify->get_field_module(), nodeset_name); Cmiss_node_id node = Cmiss_nodeset_find_node_by_identifier(nodeset, node_identifier); if (node) { return_code = field_modify->update_field_and_deaccess( Computed_field_create_nodal_lookup(field_modify->get_field_module(), source_field, node)); } else { display_message(ERROR_MESSAGE, "define field nodal lookup. Invalid node %d", node_identifier); return_code = 0; } Cmiss_node_destroy(&node); Cmiss_nodeset_destroy(&nodeset); } else { if ((!state->current_token)|| (strcmp(PARSER_HELP_STRING,state->current_token)&& strcmp(PARSER_RECURSIVE_HELP_STRING,state->current_token))) { display_message(ERROR_MESSAGE, "define_Computed_field_type_time_nodal_lookup. Failed"); } } DEALLOCATE(nodeset_name); REACCESS(Computed_field)(&source_field, NULL); } else { display_message(ERROR_MESSAGE, "define_Computed_field_type_nodal_lookup. Invalid argument(s)"); return_code = 0; } return (return_code); }
int define_Computed_field_type_quaternion_SLERP(struct Parse_state *state, void *field_modify_void, void *computed_field_lookup_package_void) /******************************************************************************* LAST MODIFIED : 25 August 2006 DESCRIPTION : Converts <field> into type 'quaterions' (if it is not already) and allows its contents to be modified. ==============================================================================*/ { int return_code; Computed_field_lookup_package *computed_field_lookup_package; Computed_field_modify_data *field_modify; ENTER(define_Computed_field_type_quaternion_SLERP); if (state&&(field_modify=(Computed_field_modify_data *)field_modify_void) && (computed_field_lookup_package= (Computed_field_lookup_package *) computed_field_lookup_package_void)) { return_code = 1; Cmiss_field_id source_field = 0; char *nodeset_name = duplicate_string("cmiss_nodes"); char node_flag = 0; int node_identifier = 0; if ((NULL != field_modify->get_field()) && (computed_field_quaternion_SLERP_type_string == Computed_field_get_type_string(field_modify->get_field()))) { Cmiss_node_id lookup_node = 0; return_code = Computed_field_get_type_quaternion_SLERP(field_modify->get_field(), &source_field, &lookup_node); if (source_field) { ACCESS(Computed_field)(source_field); } if (lookup_node) { node_identifier = get_FE_node_identifier(lookup_node); FE_region *fe_region = FE_node_get_FE_region(lookup_node); if (!FE_region_contains_FE_node(fe_region, lookup_node)) { DEALLOCATE(nodeset_name); nodeset_name = duplicate_string("cmiss_data"); } node_flag = 1; } } Option_table *option_table = CREATE(Option_table)(); Option_table_add_help(option_table, "A 4 components quaternion field. The components of " "the quaternion field are expected to be the w, x, y, z components" "of a quaternion (4 components in total). The quaternion field is" "evaluated and interpolated using SLERP at a normalised time between two" "quaternions (read in from the exnode generally). This quaternion field" "can be convert to a matrix with quaternion_to_matrix field, the resulting" "matrix can be used to create a smooth time dependent rotation for an object" "using the quaternion_to_matrix field. This field must be define directly from" "exnode file or from a matrix_to_quaternion field"); Set_Computed_field_conditional_data set_source_field_data; set_source_field_data.computed_field_manager = field_modify->get_field_manager(); set_source_field_data.conditional_function = Computed_field_has_4_components; set_source_field_data.conditional_function_user_data = (void *)NULL; Option_table_add_entry(option_table, "field", &source_field, &set_source_field_data, set_Computed_field_conditional); /* identifier of the node to lookup */ Option_table_add_entry(option_table, "node", &node_identifier, &node_flag, set_int_and_char_flag); /* the nodeset the node is from */ Option_table_add_string_entry(option_table, "nodeset", &nodeset_name, " NODE_GROUP_FIELD_NAME|[GROUP_NAME.]cmiss_nodes|cmiss_data[cmiss_nodes]"); return_code = Option_table_multi_parse(option_table, state); DESTROY(Option_table)(&option_table); if (return_code && node_flag) { Cmiss_nodeset_id nodeset = Cmiss_field_module_find_nodeset_by_name(field_modify->get_field_module(), nodeset_name); Cmiss_node_id node = Cmiss_nodeset_find_node_by_identifier(nodeset, node_identifier); if (node) { return_code = field_modify->update_field_and_deaccess( Computed_field_create_quaternion_SLERP(field_modify->get_field_module(), source_field, node)); } else { display_message(ERROR_MESSAGE, "define field quaternion_SLERP. Invalid node %d", node_identifier); return_code = 0; } Cmiss_node_destroy(&node); Cmiss_nodeset_destroy(&nodeset); } else { if ((!state->current_token)|| (strcmp(PARSER_HELP_STRING,state->current_token)&& strcmp(PARSER_RECURSIVE_HELP_STRING,state->current_token))) { display_message(ERROR_MESSAGE, "define_Computed_field_type_quaternion_SLERP. Failed"); } } DEALLOCATE(nodeset_name); REACCESS(Computed_field)(&source_field, NULL); } else { display_message(ERROR_MESSAGE, "define_Computed_field_type_quaternion_SLERP. Invalid argument(s)"); return_code = 0; } LEAVE; return (return_code); } /* define_Computed_field_type_quaternion_SLERP */